我有 10 个模型,想将这些模型组合在一起。我需要以非常非常快的响应时间做出推断。
首先我定义了容器:
// model containder
std::vector<std::shared_ptr<LRModel>> container;
// predictions, n_models = 10
std::vector<std::vector<std::string>> pred_2d(n_models);
然后我使用线程池进行并发预测:
std::vector<std::thread> threads;
for (int i = 0; i < n_models; ++i) {
threads.emplace_back(std::thread(&Search::make_infer, this,
std::ref(container[i]),
std::ref(input),
std::ref(pred_2d[i])));
}
Search::make_infer
定义为:
container[i]->predict(input, pred);
通过这样做,响应时间从 80 毫秒减少到 40 毫秒。但仍远未满足。我需要将时间减少到 10 毫秒。我该如何进一步优化它?
最佳答案
一般规则是衡量,然后再衡量一些,所以使用工具来衡量你的时间去了哪里。但仍有一些事情您应该始终注意。
如果您的所有数据都已在内存中,作为一般规则,您应该创建的线程数不要超过硬件线程数,而是让每个线程处理多个搜索。任务切换需要大约 1000 个周期到 20000ns,这取决于你有多幸运。
创建线程也不是免费的,所以如果你不能在你的 CPU 中使用额外的线程,你可以在那里节省一点,如果你多次运行这个更好,你可以使用线程池。
如果您的数据不在内存中,则更多线程可能会有所帮助,因为一些线程可以等待其他线程继续处理。
接下来减少共享数据量,在您的情况下,这似乎只是对容器的访问。如果您的 3 个 std::ref
中的每一个都只被访问一次,那将无关紧要,但我们看不到 predict
做了什么,所以也可能存在问题。如果您只从 vector
中读取,那么问题不大。
如果每个 predict
都花费相同的时间,并且您没有一个硬件线程对应每个,则最小运行时间为
time = time(predict)*num_predict/num_hardware_threads
并且您的运行时间受到最慢的软件/硬件线程组合、任务切换、系统调用、真/假共享等的限制。
还有为什么要使用 std::ref
,您的数据似乎无论如何都可以用作引用。
如果您不打算更改输入参数,您还应该使用它们的 const
版本作为参数传递。
关于c++ - 如何提高集成模型的推理时间,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47847053/