Faiss使用多线程出现的性能问题
faiss在增加CPU的情况下,反而出现效率低下的问题。
从理论上看,作为一个CPU/GPU计算型的应用,更多的核意味着更大的计算吞吐能力,性能只会越来越好才是。
在实际过程中,通过taskset命令分配更多的核给faiss只会带来更长响应时间以及更大的响应时间偏差(variation)。
faiss的主要流程:建库(train)、校验(sanity check)、搜索。
由于建库是一次性操作,就不考虑建库带来的影响。对校验分析,也没有发现需要耗时太多的时间,那么主要问题就在搜索上面。
对于”核心越多,性能越差”的奇怪表现,搜索阶段又分两个部分,一个是quantizer,一个是search_preassigned。考虑应该跟线程的计算有关,于是将nprobe值和batch设置强置为1,从算法上保证search_preassigned只能用单核单线程。结果发现多核cpu依然满载。
那么直接用perf top命令查看系统调用栈。发现在多核、单线程的模式下占比最高的居然是libgomp,而真正的benchmark(6-IVFPQ)只占了很少的CPU资源。
这就是核心的问题了:
剩下的就是解这个问题了,那只要在合适的时候让线程池销毁所有线程就迎刃而解了。OpenMP的实现是基于编译器的,发现没有办法可以直接实现目的,只有两个对应的环境变量可以缓解:
看上去效果还是不错的。
PS:并没有对所有情况进行测试,现在的结果指向是由于faiss依赖的openblat库中额外的omp线程池出现了问题导致主线程性能受到影响。理论上多线程也会如此,只是概率上导致看上去性能不是线性下降。
然后OMP_WAIT_POLICY的问题,主要是对在openmp下使用OpenBLAS的BLAS实现的时候起作用,此外,如果用了MKL库,一定条件下的MKL同样也会触发。
然后在faiss建立索引(train),也可能会出现这种情况,使用最新的faiss1.6.5及以后建立索引,CPU占用率明显有下降。
参考:http://www.litrin.net/2020/03/26/faiss的多线程效率问题/
https://www.cnblogs.com/yhzhou/p/10568728.html
https://www.cnblogs.com/yangyangcv/archive/2012/03/23/2413335.html
原文:https://www.cnblogs.com/DWVictor/p/15210985.html