多个 OpenMP 线程读取(不写入)共享变量的性能成本?

Posted

技术标签:

【中文标题】多个 OpenMP 线程读取(不写入)共享变量的性能成本?【英文标题】:Performance cost to multiple OpenMP threads reading (not writing) a shared variable? 【发布时间】:2017-08-06 21:19:02 【问题描述】:

在 OpenMP(我使用 C++)中,如果您有一个共享(甚至是全局)变量被多个线程重复读取(而不是写入),是否会产生性能成本?我知道如果他们正在写入变量,这将是不正确的。我特别问的是只读 - 如果多个线程重复读取同一个变量,是否有潜在的性能成本?

【问题讨论】:

【参考方案1】:

如果您只是阅读,那么您没有安全问题。一切都会好起来的。根据定义,您没有Race Conditions。您不需要进行任何锁定,因此不会发生high-contention 问题。您可以使用Clang ThreadSanitizer 在运行时测试线程安全性。

另一方面,需要注意一些性能问题。尽量避免false sharing,让每个线程(或者最好是所有线程)一次访问内存中连续的一堆数据。这样,当 CPU 缓存加载数据时,就不需要每时每刻多次访问内存。与访问 CPU 缓存相比,访问内存被认为非常昂贵(至少慢数百倍)。

祝你好运!

【讨论】:

【参考方案2】:

如果变量(更精确的内存位置)只被所有线程读取,那么在正确性和性能方面基本上都很好。缓存协议具有“共享”状态 - 因此值可以缓存在多个内核上。

但是,您还应该避免将数据写入与变量相同的缓存行,因为这会使其他内核的缓存无效。同样在 NUMA 系统上,您必须考虑读取某些内核/线程的某些内存区域可能会更昂贵。

【讨论】:

以上是关于多个 OpenMP 线程读取(不写入)共享变量的性能成本?的主要内容,如果未能解决你的问题,请参考以下文章

OpenMP 子句共享与关键

我可以使用 OpenMP 通过单个线程释放共享变量吗?

允许多个线程一次读取给定条件变量,但只有一个线程写入

功能联锁交换

Java volatile关键字介绍

OpenMP 的全局变量