gpt4 book ai didi

c++ - OpenMP 循环数组访问中的错误共享

转载 作者:搜寻专家 更新时间:2023-10-31 01:31:47 25 4
gpt4 key购买 nike

我想利用 OpenMP 使我的任务并行进行。

我需要对数组的所有元素减去相同的数量,并将结果写入另一个 vector 。两个数组都是用 malloc 动态分配的,第一个数组是用文件中的值填充的。每个元素都是 uint64_t 类型。

#pragma omp parallel for
for (uint64_t i = 0; i < size; ++i) {
new_vec[i] = vec[i] - shift;
}

其中 shift 是我要从 vec 的每个元素中删除的固定值。 sizevecnew_vec的长度,约为200k。

我在 Arch Linux 上使用 g++ -fopenmp 编译代码。我在 Intel Core i7-6700HQ 上,使用 8 个线程。当我使用 OpenMP 版本时,运行时间增加了 5 到 6 倍。当我运行 OpenMP 版本时,我可以看到所有内核都在工作。

我认为这可能是由 False Sharing 问题引起的,但我找不到它。

最佳答案

您应该调整迭代在线程之间的分配方式。使用 schedule(static,chunk_size) 您可以这样做。

尝试使用 chunk_size 值的 64/sizeof(uint64_t) 的倍数来避免上述错误共享:

[ cache line n   ][ cache line n+1 ]
[ chuhk 0 ][ chunk 1 ][ chunk 2 ]

并实现这样的目标:

[ cache line n   ][ cache line n+1 ][ cache line n+2 ][...]
[ chunk 0 ][ chunk 1 ]

您还应该以与缓存行对齐的方式分配 vector 。这样您就可以确保第一个和后续的 block 也正确对齐。

#define CACHE_LINE_SIZE sysconf(_SC_LEVEL1_DCACHE_LINESIZE) 
uint64_t *vec = aligned_alloc( CACHE_LINE_SIZE/*alignment*/, 200000 * sizeof(uint64_t)/*size*/);

你的问题真的很像Stream Triad benchmark代表。查看how to optimize that benchmark您将能够几乎准确地映射代码的优化。

关于c++ - OpenMP 循环数组访问中的错误共享,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45032586/

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