我正在编写一个具有多个分支的递归树搜索,并且工作正常。为了加快速度,我正在实现一个简单的多线程:我将搜索分布到主分支中并将它们分散在线程中。每个线程不必与其他线程交互,当找到解决方案时,我使用互斥体将其添加到公共(public) std::vector 中:

if (CubeTest.IsSolved()) 
{ // Solve algorithm found 
    std::lock_guard<std::mutex> guard(SearchMutex); // Thread safe code 
    Solves.push_back(Alg);  // Add the solve 
} 

我不会使用newdelete在动态存储(堆)中分配变量,因为内存需求很小。 我使用的最大线程数是我从以下位置获得的数量:std::thread::hardware_concurrency()

我做了一些测试,总是相同的搜索,但改变了使用的数量或线程,并且我发现了我没有预料到的东西。 我知道,如果将线程数量加倍(如果处理器有足够的容量),由于上下文切换等原因,您不能指望性能加倍。

例如,我有一台旧的 Intel Xeon X5650,6 核/12 线程。如果我执行我的代码,直到第六个线程,事情都会按预期进行,但如果我使用额外的线程,性能会最差。使用更多线程对性能的提高很小,以至于使用所有可用线程 (12) 几乎无法补偿仅使用 6 个线程:

Xeon X5650 的线程与处理时间图表:

(我重复测试几次,并显示所有测试的平均时间)。

我在另一台配备 Intel i7-4600U(2 核/4 线程)的计算机上重复测试,我发现:

i7-4600U 的线程与处理时间图表:

据我了解,如果内核数较少,使用更多线程的性能提升效果最差。

我还认为,当您开始在同一核心中使用第二个线程时,性能会以某种方式受到影响。我对吗?在这种情况下如何提高性能?

所以我的问题是,多线程的性能提升是否是我在现实世界中所期望的,或者另一方面,这些数字告诉我我做错了,我应该了解更多有关多线程编程的知识。

请您参考如下方法:

What's the “real world” performance improvement for multithreading I can expect?

这取决于很多因素。一般来说,人们可以期望的最乐观的改进是运行时间减少核心数量1。在大多数情况下,这是无法实现的,因为线程需要彼此同步。

在最坏的情况下,不仅由于缺乏并行性而没有任何改进,而且同步的开销以及缓存争用也会使运行时比单线程程序差很多。

峰值内存使用通常随线程数量线性增加,因为每个线程都需要操作自己的数据。

由于同步花费了额外的时间,总 CPU 时间使用量以及能源使用量也会增加。这与使用电池供电的系统以及热管理较差的系统有关(均适用于手机和笔记本电脑)。

由于处理线程的额外代码,二进制大小会稍微大一些。


1 是否从“逻辑”核心(即“超线程”或“集群多线程”)获得所有性能还取决于许多因素。通常,一个人在所有线程中执行相同的函数,在这种情况下,它们往往会使用 CPU 的相同部分,在这种情况下,与多个线程共享核心并不一定会产生好处。


评论关闭
IT序号网

微信公众号号:IT虾米 (左侧二维码扫一扫)欢迎添加!