Shr*_*roy 20 c++ multithreading multicore
我有vector<int>10,000,000(1000万)个元素,我的工作站有四个核心.有一个函数叫做ThrFunc整数运算.假设ThrFunc每个整数的运行时间vector<int>大致相同.
我应该如何确定要触发的最佳线程数?答案就像元素数量除以核心数一样简单吗?或者是否有更微妙的计算?
编辑以提供额外信息
Bor*_*lid 24
最佳线程数可能是计算机中的核心数或核心数乘以2.
在更抽象的术语中,您需要尽可能高的吞吐量.获得最高吞吐量需要线程之间的争用点最少(因为原始问题可以简单地并行化).争用点的数量可能是共享核心的线程数或两倍,因为核心可以运行一个或两个逻辑线程(两个具有超线程).
如果您的工作负载使用的资源少于四个(Bulldozer上的ALU?硬盘访问?),那么您应该创建的线程数将受到限制.
找出正确答案的最佳方法是,通过所有硬件问题,进行测试和发现.
sar*_*old 12
Borealid的答案包括测试和发现,这是不可能的建议.
但是测试这个可能比你想象的要多:你希望你的线程尽可能避免争用数据.如果数据完全是只读的,那么如果您的线程正在访问"相似"数据,您可能会看到最佳性能 - 确保一次以小块方式遍历数据,因此每个线程都从相同的页面访问数据一遍又一遍.如果数据是完全只读的,那么如果每个核心都有自己的缓存行副本就没有问题.(虽然这可能无法充分利用每个核心的缓存.)
如果数据以任何方式被修改,那么如果您将线程彼此远离,您将看到显着的性能增强.大多数缓存都沿着缓存行存储数据,并且您迫切希望防止每个缓存行在CPU之间弹跳以获得良好的性能.在这种情况下,您可能希望保持不同的线程在实际相距很远的数据上运行,以避免相互碰撞.
所以:如果你在处理数据时更新数据,我建议使用N或2*N个执行线程(对于N个内核),以SIZE/N*M为起点开始,对于0到0的线程M.(0,1000,2000,3000,用于四个线程和4000个数据对象.)这将为您提供向每个核心提供不同缓存行的最佳机会,并允许更新继续进行而不会缓存行缓存:
+--------------+---------------+--------------+---------------+--- ...
| first thread | second thread | third thread | fourth thread | first ...
+--------------+---------------+--------------+---------------+--- ...
Run Code Online (Sandbox Code Playgroud)
如果您在处理数据时没有更新数据,您可能希望启动N或2*N个执行线程(对于N个内核),以0,1,2,3等启动它们并移动每个线程.每次迭代前进N或2*N个元素.这将允许缓存系统从内存中获取每个页面一次,用几乎相同的数据填充CPU缓存,并希望保持每个核心填充新数据.
+-----------------------------------------------------+
| 1 2 3 4 1 2 3 4 1 2 3 4 1 2 3 4 1 2 3 4 1 2 3 4 ... |
+-----------------------------------------------------+
Run Code Online (Sandbox Code Playgroud)
我还建议sched_setaffinity(2)在代码中直接使用强制不同的线程到自己的处理器.根据我的经验,Linux的目标是将每个线程保留在其原始处理器上,以免将任务迁移到其他空闲的核心.
假设ThrFunc受 CPU 限制,那么您可能需要每个核心一个线程,并在它们之间划分元素。
如果函数有一个 I/O 元素,那么答案会更复杂,因为每个核心可以有一个或多个线程在另一个正在执行时等待 I/O。做一些测试,看看会发生什么。
| 归档时间: |
|
| 查看次数: |
6099 次 |
| 最近记录: |