我有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);
这样,响应时间从80ms减少到40ms。但是仍然远远不满意。我需要将时间减少到10ms。我该如何进一步优化?
最佳答案
一般规则是衡量,然后再衡量一些,因此请使用工具衡量时间。但是,您仍然应该注意一些事项。
如果所有数据都已存储在内存中,那么一般来说,您的线程数不应超过硬件线程数,而应让每个线程处理多个搜索。根据您的幸运程度,任务切换大约需要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/