gpt4 book ai didi

c++ - 多线程代码中的简单数组写入比单线程慢

转载 作者:行者123 更新时间:2023-11-27 22:36:39 25 4
gpt4 key购买 nike

我正在尝试并行化代码。但是我注意到 C++ 中有一个奇怪的行为。我将问题简化为以下内容:我有一个巨大的数组(100M 字节)。当我在单个线程中在此数据上写入随机数据时,它比并行运行(例如 10 核)快得多。我假设通过考虑超过 1GB/s 的 RAM 速度,在 RAM 上并行写入应该没有任何问题。代码是这样的:

#include <iostream>
#include <type_traits>
#include <stdio.h>
#include <stdlib.h>
#include <cstring>
#include <chrono>
#include <thread>
using namespace std;

uint8_t g[16]{1, 2, 3, 4, 5, 6, 7, 8, 9, 11, 12, 13, 14, 15, 10, 1};

uint8_t** data = new uint8_t*[1000];

void test() {
for (int i = 1; i < 100000000; i++) {
int row = rand() % 1000;
int col = rand() % 10000000;
memcpy(&data[row][col], &g[0], 16);
memcpy(&data[row][col + 16], &g[0], 16);
}
}
#define TH 1

int main() {
for (int i = 0; i < 1000; i++) {
data[i] = new uint8_t[10000000];
}
std::chrono::time_point<std::chrono::high_resolution_clock> m_beg = std::chrono::high_resolution_clock::now();
std::thread* workers = new std::thread[TH];
for (int i = 0; i < TH; i++) {
workers[i] = std::thread(&test);
}
for (int i = 0; i < TH; i++) {
workers[i].join();
}

double t = std::chrono::duration_cast<std::chrono::microseconds>(std::chrono::high_resolution_clock::now() - m_beg).count();
cout << t << endl;
}

我比较了设置:

1-TH=1 , 测试循环计数器=100M

2-TH=10,测试循环计数器=10M

结果如下:

1-10秒

2-72秒

有谁知道是什么原因吗?

最佳答案

您的所有线程都以随机方式访问相同的数据。

每次一个线程向一个位置写入内容时,所有具有该值的缓存行都将失效并且必须更新。这种情况一直发生在您的所有线程上,随时使所有缓存中的数据失效。

这与锁无关,而是关于必须使具有相同数据的其他内核的缓存行失效这一事实。这是有代价的。

想象一下,您在一面小墙上有 1000000 个螺钉。你有十个人用十把 Screwdriver 。他们都会互相妨碍,因为如果他们想在同一位置的两个螺丝上工作,他们可以高效地工作。这里也有点像这样,但层次结构更多。

关于c++ - 多线程代码中的简单数组写入比单线程慢,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53335089/

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