让我们来创建一个非常简单的C++类,它只有一个数据成员:
class Container {
public:
std::vector<Element> elements;
Container(int elemCount);
};
现在创建N个线程,它们执行一个非常简单的任务:
- 创建一个本地容器并设置特定的向量大小
- 循环遍历该向量并逐个增加每个元素的值
- 重复步骤2 10,000次(以秒为单位而不是毫秒)
根据CoreInfo,我的CPU(Intel Core i5 2400)有4个核心,每个核心都有自己的L1/L2缓存。
Logical to Physical Processor Map:
*--- Physical Processor 0
-*-- Physical Processor 1
--*- Physical Processor 2
Logical Processor to Cache Map:
*--- Data Cache 0, Level 1, 32 KB, Assoc 8, LineSize 64
*--- Instruction Cache 0, Level 1, 32 KB, Assoc 8, LineSize 64
*--- Unified Cache 0, Level 2, 256 KB, Assoc 8, LineSize 64
-*-- Data Cache 1, Level 1, 32 KB, Assoc 8, LineSize 64
-*-- Instruction Cache 1, Level 1, 32 KB, Assoc 8, LineSize 64
-*-- Unified Cache 1, Level 2, 256 KB, Assoc 8, LineSize 64
--*- Data Cache 2, Level 1, 32 KB, Assoc 8, LineSize 64
--*- Instruction Cache 2, Level 1, 32 KB, Assoc 8, LineSize 64
--*- Unified Cache 2, Level 2, 256 KB, Assoc 8, LineSize 64
---* Data Cache 3, Level 1, 32 KB, Assoc 8, LineSize 64
---* Instruction Cache 3, Level 1, 32 KB, Assoc 8, LineSize 64
---* Unified Cache 3, Level 2, 256 KB, Assoc 8, LineSize 64
**** Unified Cache 4, Level 3, 6 MB, Assoc 12, LineSize 64
---* Physical Processor 3
对于向量大小最多为100,000个元素,计时与预期完全相符:
Elements count: 100.000
Threads: 1
loops: 10000 ms: 650
Threads: 4
loops: 2500 ms: 168
loops: 2500 ms: 169
loops: 2500 ms: 169
loops: 2500 ms: 171
然而,对于更大的向量尺寸,多核性能表现如下:
Elements count: 300.000
Threads: 1
loops: 10000 ms: 1968
Threads: 4
loops: 2500 ms: 3817
loops: 2500 ms: 3864
loops: 2500 ms: 3927
loops: 2500 ms: 4008
我的问题:
- 请问有人能向我解释这个原因吗?这是假共享吗?如果是,如果线程不共享任何数据,并且所有核心都有自己的L1/L2高速缓存和缓存行,那么这是怎么可能的?
- 如果在多个线程中处理独立数据,是否有可能实现(或接近)线性加速效率?
编辑:感谢所有回答。关于您的问题:
@user2079303:Element仅包含一个双精度数据成员。sizeof(Element)=8。请参见Pastebin获取完整源代码。
@bku_drytt:resize()是正确的。我的意图是在每个线程中创建一个包含elemCount元素的向量(无论它们的初始值如何)。
@Jorge González Lorenzo:您在共享的L3缓存方面是绝对正确的。我进行了另一组测试,仅使用单个线程:
Elements count: 50.000
Threads: 1
loops: 50000 ms: 1615
Elements count: 200.000 (4 times bigger)
Threads: 1
loops: 50000 ms: 1615 (slightly more than 4 time bigger)
Elements count: 800.000 (even 4 times bigger)
Threads: 1
loops: 50000 ms: 42181 (MUCH more than 4 time bigger)
Element
有多大?你记得启用优化编译吗? - eerorikaresize()
而不是reserve()
吗? - bku_drytt