From 4ae4abbe433298561cecbff87217d6c7aa692d8c Mon Sep 17 00:00:00 2001 From: Alberto Ferreira Date: Thu, 21 Jan 2021 15:58:28 +0000 Subject: [PATCH] Fix thread-safety in C API's PredictSingleRow (#3771) By using a unique lock instead of the shared lock the timings are very similar, but predictions are correct. Even so, by designing a small C++ benchmark with a very simple LGBM model,more threads on a simple model are slower than the single-thread case. This is probably due to very small work units, the lock contention overhead increases. We should in the future benchmark with more complex models to see if supporting threading on these calls is worth it in performance gains. If not, then we could choose to not to provide thread-safety and remove the locks altogether for maximal throughput. See https://github.com/microsoft/LightGBM/issues/3751 for timings. See gist for benchmark code: https://gist.github.com/AlbertoEAF/5972db15a27c294bab65b97e1bc4c315 --- src/c_api.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/c_api.cpp b/src/c_api.cpp index 25ef5802ee13..47d7f8fef8de 100644 --- a/src/c_api.cpp +++ b/src/c_api.cpp @@ -389,7 +389,7 @@ class Booster { Log::Fatal("The number of features in data (%d) is not the same as it was in training data (%d).\n"\ "You can set ``predict_disable_shape_check=true`` to discard this error, but please be aware what you are doing.", ncol, boosting_->MaxFeatureIdx() + 1); } - SHARED_LOCK(mutex_) + UNIQUE_LOCK(mutex_) const auto& single_row_predictor = single_row_predictor_[predict_type]; auto one_row = get_row_fun(0); auto pred_wrt_ptr = out_result;