gpt4 book ai didi

c++ - std::thread 的线程安全数组?

转载 作者:塔克拉玛干 更新时间:2023-11-03 01:36:44 30 4
gpt4 key购买 nike

mystruct** = (mystruct**)calloc(10, sizeof(mystruct*);
for(unsignd int i = 0; i < 10; i++)
mystruct[i] = (mystruct*)calloc(10, sizeof(mystruct);

thread t[10];

for(unsigned int i = 0; i < 10; i++)
t[i] = thread(new_piece, mystruct[i]);

for(unsigned int i = 0; i < 10; i++)
t[i].join();

函数 new_piece 将数据写入 mystruct[i]。更具体地说,该函数更改了 mystruct[i][0], mystruct[i][1], ..., mystruct[9]

的值

如何让上面的操作线程安全?

最佳答案

正如评论中已经提到的,该代码似乎是“线程安全的”,但它可能会遭受“缓存抖动”的困扰。

首先让我解释一下它是什么,以及为什么这可能会在您的代码中发生:

什么是缓存抖动:

“缓存行”是从内存中提取到缓存中的最小数据单元。请注意,缓存行的大小是硬件属性。没有可以产生此值的语言结构。现代 CPU 上的大多数缓存行大小为 64 字节。

缓存抖动发生在具有多个 CPU 和一致缓存的系统上,当不同的线程访问不同的变量时,这些变量恰好位于共享同一缓存行的内存中。这将导致过多的缓存未命中,从而导致性能下降。

(另见 wiki 文章 false-sharing)指的是导致缓存抖动的使用模式)

(另请参阅:Dobb 博士的文章 Eliminate False Sharing)

为什么它会在您的代码中发生:

calloc 返回的分配 block 或 malloc力求尽可能小,并紧紧地挤在一起。也就是说,不同的分配 block 可能共享相同的缓存行(另请参见 man 3 calloc ,例如 FreeBSD man page )。

C++ 的 new运算符不会有所不同。

现在,我们不能普遍假设从 calloc 返回的内存块或 malloc不会共享一个公共(public)缓存行,您的代码可能会遭受缓存抖动,因为从不同线程同时访问的 mystruct 实例可能共享一个公共(public)缓存行。

如何避免“缓存抖动”:

基本上,您可以通过正确对齐数据来确保这一点(请参阅维基文章 Data Structure Alignment)。

有许多方法可以确保您的数据 (mystruct) 正确缓存对齐,例如:

  • 使用 malloccalloc并将您的分配请求四舍五入到缓存行大小的最接近倍数。

  • 利用一个 posix 函数:posix_memalign , 在 header 中声明 <stdlib.h> (参见开放组 posix_memalign)

  • 在 C++11 中,您可以使用 std::aligned_storage (见定义here)

    std::aligned_storage提供 type适合用作未初始化存储,您可以在其中存储对象。

    例如,定义一个缓存行对齐的存储,它是一个包含 N 个实例的数组:

    struct mystruct { ... };

    const std::size_t cache_line_size = 64;

    typename std::aligned_storage<sizeof(mystruct), cache_line_size>::type storage[N];

    有了它,您现在可以定义一个类,它包装一个 N 缓存行对齐 mystruct 的数组。 s,它还提供方便的访问器函数来修改和检索 mystruct底层数组中 i 位置的值。 IMO,这种方法比使用循环和 calloc 为您的 mystruct 实例化存储的容易出错的方法更可取。数组。

    参见示例 here ,稍作修改即可完美满足您的需求。

关于c++ - std::thread 的线程安全数组?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21715072/

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