gpt4 book ai didi

c++ - 在 C++ STL 类型的静态实例上使用 OpenMP threadprivate 指令

转载 作者:塔克拉玛干 更新时间:2023-11-02 23:41:46 26 4
gpt4 key购买 nike

考虑以下片段:

#include <map>

class A {
static std::map<int,int> theMap;
#pragma omp threadprivate(theMap)
};

std::map<int,int> A::theMap;

使用 OpenMP 编译失败并显示以下错误消息:

$ g++ -fopenmp -c main.cpp 
main.cpp:5:34: error: ‘threadprivate’ ‘A::theMap’ has incomplete type

我不明白这个。我可以在没有 #pragma 指令的情况下进行编译,这应该意味着 std::map 不是不完整。如果 theMap 是原始类型(double、int...),我也可以编译。

如何创建全局静态 std::map threadprivate

最佳答案

这是一个编译器限制。英特尔 C/C++ 编译器支持 threadprivate 上的 C++ 类,而 gcc 和 MSVC 目前不支持。

例如,在 MSVC (VS 2010) 中,你会得到这个错误(我删除了类):

static std::map<int,int> theMap;
#pragma omp threadprivate(theMap)

error C3057: 'theMap' : dynamic initialization of 'threadprivate' symbols is not currently supported

所以,解决方法很明显,但是很脏。您需要制作一个非常简单的线程本地存储。一个简单的方法是:

const static int MAX_THREAD = 64;

struct MY_TLS_ITEM
{
std::map<int,int> theMap;
char padding[64 - sizeof(theMap)];
};

__declspec(align(64)) MY_TLS_ITEM tls[MAX_THREAD];

请注意,我有填充的原因是为了避免 false sharing .我假设现代 Intel x86 处理器的 64 字节高速缓存行。 __declspec(align(64)) 是一个 MSVC 扩展,该结构位于 64 的边界上。因此,tls 中的任何元素都将位于不同的缓存行上,导致没有虚假共享。 GCC 具有 __attribute__ ((aligned(64)))

为了访问这个简单的 TLS,您可以这样做:

tls[omp_get_thread_num()].theMap;

当然,您应该在 OpenMP 并行结构之一中调用它。好消息是 OpenMP 在 [0, N) 中提供了一个抽象的线程 ID,其中 N 是最大线程数。这可以实现快速简单的 TLS 实现。通常,来自操作系统的 native TID 是任意整数。因此,您最需要的是一个哈希表,其访问时间比简单数组长。

关于c++ - 在 C++ STL 类型的静态实例上使用 OpenMP threadprivate 指令,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8051108/

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