gpt4 book ai didi

C++ 独立数据的多线程性能

转载 作者:塔克拉玛干 更新时间:2023-11-03 02:22:18 25 4
gpt4 key购买 nike

让我们创建一个只有一个数据成员的非常简单的 C++ 类:

class Container {
public:
std::vector<Element> elements;
Container(int elemCount);
};

现在创建 N 个线程来完成一个非常简单的任务:

  1. 创建一个具有特定 vector 大小的本地 Container
  2. 遍历 vector 并简单地增加每个元素的 val
  3. 重复步骤 2 10.000 次(以秒而不是毫秒为单位获取时间)

完整的代码 list 可以在 Pastebin 上找到

根据 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 个元素的 vector ,时间完全符合预期:

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

但是,对于更大的 vector 大小,多核的性能是:

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

我的问题:

  1. 有人可以向我解释一下这是什么原因吗?这是虚假分享吗?如果是这样,如果线程共享任何数据并且所有内核都有自己的 L1/L2 缓存和缓存行,这怎么可能?
  2. 在多线程处理独立数据时,能否达到(或接近)线性提速效率?

编辑:感谢所有回答,到目前为止。关于您的问题:

@user2079303:元素只包含一个双数据成员。大小(元素)=8。请看Pastebin完整的源代码。

@bku_drytt:resize() 是正确的。我的意图是在每个线程中创建一个包含 elemCount 元素的 vector (不管它们的初始值如何)。

@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)

最佳答案

您正在使用 4 个线程填充 L3 共享缓存(需要 x4 存储,因为每个线程有一个 vector ),因此导致许多缓存未命中,而在单线程执行中, vector 适合它。 L1 和 L2 按核心计算,但 L3 不是。一个公平的比较是使用比 4 线程执行大 4 倍的 vector 来运行单线程执行。

关于C++ 独立数据的多线程性能,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33733589/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com