在多线程里要做到的真正的平行计算简直不可能
最近折腾了很久一个关于平行计算的程序,我测试的机器算比较牛的了,16个核,内存16个G。当然,我程序只能用4G。
我要做的不过是启动四个或者8个线程同时运行一个相同的算法。线程间就我写的部分肯定没有任何资源需要共享,也就是说线程间没有任何互斥。 结果跑起来的结果让我大跌眼镜,启动4个线程的时候,同样的算法,时间比只有一个线程比起来多了差不多50%,8个线程的时候,直接翻倍还要多。
这个时候我唯一能想到的就是内存这个东西了各个线程是需要竞争的了,于是我替换了intel 的tbb::scalable_alloc(有点像广告),结果好了一点点,也就是好了10%的样子。
我的算法里面new 和 delete这些有一些,但是在现代程序里面绝对算是正常的。
我大刀阔斧地简化了我的算法,发现只有当简化到一定程度时,使用tbb::scalable_alloc的优势才体现出来,基本可以实现跑8个线程和跑1个线程时时间一样。但是算法一旦复杂,包括程序的结构(链接多个动态库什么的),tbb基本上就没什么优势了。
如果我不用多线程,直接用多进程,比如启动8个进程,执行时间和只有一个进程运行时一模一样(这个倒是不奇怪,16个核在哪呢,可不是来打酱油的)。
我现在真的很好奇到底是什么东西影响了多线程的运行效率,互斥我是可以保证没有的。分配内存的问题按道理tbb::scalable_alloc可以解决,至少程序够简单的时候是解决了的。难道最终还是内存分配问题影响了线程的效率? 还有没有其他的东西会影响呢?
另外就是,如果执行算法的时间如果长,比如需要十秒左右,这个时候跑8个线程和跑1个线程的执行时间就完全一样了。这也是为什么我敢保证线程之间肯定没有互斥的原因,如果有的话, 不管执行多长时间,8个线程的时间都不会和1个线程一样。
哪位对多核运算厉害的牛人能解答一下我遇到的这些神秘现象呢?三跪九叩首了