c++ - Intel 上的多线程比 AMD 慢得多

标签 c++ multithreading concurrency c++11

我想让下面的代码并行化:

for(int c=0; c<n; ++c) {
    Work(someArray, c);
}

我是这样做的:

#include <thread>
#include <vector>

auto iterationsPerCore = n/numCPU;
std::vector<std::future<void>> futures;

for(auto th = 0; th < numCPU; ++th) {
    for(auto n = th * iterationsPerCore; n < (th+1) * iterationsPerCore; ++n) {
        auto ftr = std::async( std::launch::deferred | std::launch::async,
            [n, iterationsPerCore, someArray]()
            {
                for(auto m = n; m < n + iterationsPerCore; ++m)
                    Work(someArray, m);
            }
        );
        futures.push_back(std::move(ftr));
    }

    for(auto& ftr : futures)
        ftr.wait();
}

// rest of iterations: n%iterationsPerCore
for(auto r = numCPU * iterationsPerCore; r < n; ++r)
    Work(someArray, r);

问题是它在 Intel CPU 上的运行速度只有 50%,而在 AMD 上它的运行速度却快了 300%。 我在三个 Intel CPU(Nehalem 2core+HT、Sandy Bridge 2core+HT、Ivy Brigde 4core+HT)上运行它。 AMD 处理器是 Phenom II x2,4 核解锁。在 2 核 Intel 处理器上,它的运行速度提高了 50%,有 4 个线程。在 4 核上,它在 4 个线程上的运行速度也提高了 50%。我正在使用 VS2012、Windows 7 进行测试。

当我尝试使用 8 个线程时,它比 Intel 上的串行循环慢 8 倍。我想这是由 HT 引起的。

你怎么看?这种行为的原因是什么?也许代码不正确?

最佳答案

我怀疑虚假分享。当两个变量共享同一缓存行时会发生这种情况。实际上,对它们的所有操作都必须非常昂贵地同步即使它们不是并发访问的,因为缓存只能根据一定大小的缓存行进行操作,即使您的操作更精细-颗粒感。我怀疑 AMD 硬件只是更有弹性,或者具有不同的硬件设计来应对这种情况。

要进行测试,请更改代码,使每个核心仅适用于 64 字节的倍数的 block 。这应该避免任何缓存行共享,因为 Intel CPU 只有 64 字节的缓存行。

关于c++ - Intel 上的多线程比 AMD 慢得多,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13847465/

相关文章:

c++ - 使用 lambda 的简单 RAII 包装器的复制初始化在 GCC 和 Clang 下意外失败

C++将可变数量的位置从给定数组传递给函数

multithreading - POSIX命名信号量可以同步线程吗?

concurrency - clojure pmap/preduce vs fork-join

ruby-on-rails - Rails 3.1 并发风险

java - 自动更新 map /集并检查大小

c++ - Boost::Pool 未链接

c++ - 我可以在类头文件中定义类的 const static 实例吗

java - Session.sendToTarget() 是线程安全的吗?

java - 如何告诉 Runnable 抛出 InterruptedException?