c++ - 简单的 C++ 循环不受益于多线程

标签 c++ multithreading

我有一些非常简单的 C++ 代码,我确信在多线程下它们的运行速度会快 3 倍,但在 Windows 10 上的 GCC 和 MSVC 上不知何故只能快 3%(或更少)。

没有互斥锁和没有共享资源。而且我看不出错误共享或缓存抖动是如何起作用的,因为每个线程只修改数组的一个不同部分,该部分具有超过十亿个 int 值。我意识到有很多关于 SO 的问题,但我还没有找到任何似乎可以解决这个特殊谜团的问题。

一个提示可能是,将数组初始化移动到 add() 函数的循环中 确实 使多线程与单线程时的函数速度提高 3 倍(~885 毫秒对比 ~2650 毫秒)。

请注意,只有 add() 函数正在计时,在我的机器上需要约 600 毫秒。我的机器有 4 个超线程内核,所以我在运行代码时将 threadCount 设置为 8,然后再设置为 1。

知道会发生什么吗?有什么方法可以关闭(在适当的时候)处理器中导致错误共享(并且可能像我们在这里看到的那样)的功能吗?

#include <chrono>
#include <iostream>
#include <thread>

void startTimer();
void stopTimer();
void add(int* x, int* y, int threadIdx);

namespace ch = std::chrono;
auto start = ch::steady_clock::now();
const int threadCount = 8;
int itemCount = 1u << 30u; // ~1B items
int itemsPerThread = itemCount / threadCount;

int main() {
    int* x = new int[itemCount];
    int* y = new int[itemCount];

    // Initialize arrays
    for (int i = 0; i < itemCount; i++) {
        x[i] = 1;
        y[i] = 2;
    }

    // Call add() on multiple threads
    std::thread threads[threadCount];
    startTimer();
    for (int i = 0; i < threadCount; ++i) {
        threads[i] = std::thread(add, x, y, i);
    }
    for (auto& thread : threads) {
        thread.join();
    }
    stopTimer();

    // Verify results
    for (int i = 0; i < itemCount; ++i) {
        if (y[i] != 3) {
            std::cout << "Error!";
        }
    }

    delete[] x;
    delete[] y;
}

void add(int* x, int* y, int threadIdx) {
    int firstIdx = threadIdx * itemsPerThread;
    int lastIdx = firstIdx + itemsPerThread - 1;

    for (int i = firstIdx; i <= lastIdx; ++i) {
        y[i] = x[i] + y[i];
    }
}

void startTimer() {
    start = ch::steady_clock::now();
}

void stopTimer() {
    auto end = ch::steady_clock::now();
    auto duration = ch::duration_cast<ch::milliseconds>(end - start).count();
    std::cout << duration << " ms\n";
}

最佳答案

您可能只是达到了机器的内存传输速率,您正在执行 8GB 的​​读取和 4GB 的写入。

在我的机器上,您的测试在大约 500 毫秒内完成,即 24GB/s(这与内存带宽测试仪给出的结果相似)。

当您通过单次读取和单次写入访问每个内存地址时,缓存没有多大用处,因为您没有重复使用内存。

关于c++ - 简单的 C++ 循环不受益于多线程,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57669273/

相关文章:

multithreading - ESRI 映射提供主线程检查器 : UI API called on a background thread in iOS 11

Java 内存模型——在跨越内存屏障时究竟将什么刷新到内存中?

java - 了解启动线程和可能涉及的数据竞争

c++ - 在 x64 系统上从 32 位应用程序使用 IFilter

c++ - 如何编写混合 C 和 C++ 的 makefile

c++ - 将 std::partition 与快速排序一起使用

c - 简单 pthread 代码中的奇怪结果

c++ - 如何设置水平标题QHeaderView的高度?

c++ - allegro5 (C++) 中的另一幅图像

multithreading - 在 delphi 2007 中启动挂起线程的正确方法是什么?