From 35ed1a65c6d69fc145939ebcc7c64ae4cc7da220 Mon Sep 17 00:00:00 2001 From: Brett Taylor Date: Fri, 10 May 2024 18:07:35 -0700 Subject: [PATCH] Improve load time on serialized entries. From profiling slow load times of serialized GPUv2 delegate data, a lot of unnecessary time is spent re-allocating memory as part of the call to std::string::append. By pre-allocating the correct size, we save a lot of time. This patch was developed in 2022 (pardon the slow turn-around) and I no longer have the exact profiling details. However, my notes say that on an arbitrary but complex model, GetData() was previously taking 50ms; with this patch, it takes 18ms. --- tensorflow/lite/delegates/serialization.cc | 37 ++++++++++++++-------- 1 file changed, 23 insertions(+), 14 deletions(-) diff --git a/tensorflow/lite/delegates/serialization.cc b/tensorflow/lite/delegates/serialization.cc index 06ad487abf5a70..29791d78fca973 100644 --- a/tensorflow/lite/delegates/serialization.cc +++ b/tensorflow/lite/delegates/serialization.cc @@ -21,6 +21,7 @@ limitations under the License. #include #include #include +#include #include #include @@ -193,22 +194,30 @@ TfLiteStatus SerializationEntry::GetData(TfLiteContext* context, std::strerror(errno)); return kTfLiteDelegateDataReadError; } - char buffer[512]; - while (true) { - int bytes_read = read(fd, buffer, 512); - if (bytes_read == 0) { - // EOF - close(fd); - return kTfLiteOk; - } else if (bytes_read < 0) { - close(fd); - TF_LITE_KERNEL_LOG(context, "Error reading %s: %s", filepath.c_str(), - std::strerror(errno)); - return kTfLiteDelegateDataReadError; - } else { - data->append(buffer, bytes_read); + + struct stat file_stat; + if (fstat(fd, &file_stat) < 0) { + close(fd); + TF_LITE_KERNEL_LOG(context, "Could not fstat %s: %s", filepath.c_str(), + std::strerror(errno)); + return kTfLiteDelegateDataReadError; + } + data->resize(file_stat.st_size); + + size_t total_read = 0; + while (total_read < data->size()) { + ssize_t bytes_read = read(fd, data->data() + total_read, data->size() - total_read); + total_read += bytes_read; + + if (bytes_read < 0) { + close(fd); + TF_LITE_KERNEL_LOG(context, "Error reading %s: %s", filepath.c_str(), + std::strerror(errno)); + return kTfLiteDelegateDataReadError; } } + + close(fd); #endif // defined(_WIN32) TFLITE_LOG_PROD(TFLITE_LOG_INFO,