我有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/

10-17 00:16