在 OpenMP 中重置线程局部变量
Reset thread-local variables in OpenMP
我需要一种一致的方式来重置程序创建的所有线程局部变量。问题在于线程本地数据的创建位置与使用它们的位置不同。
我的计划大纲如下:
struct data_t { /* ... */ };
// 1. Function that fetches the "global" thread-local data
data_t& GetData()
{
static data_t *d = NULL;
#pragma omp threadprivate(d); // !!!
if (!d) { d = new data_t(); }
return *d;
}
// 2 example function that uses the data
void user(int *elements, int num, int *output)
{
#pragma omp parallel for shared(elements, output) if (num > 1000)
for (int i = 0; i < num; ++i)
{
// computation is a heavy calculation, on memoized data
computation(GetData());
}
}
现在,我的问题是我需要一个重置数据的函数,即必须考虑创建的每个线程本地对象。
现在,我的解决方案是使用一个并行区域,希望使用与"并行"相等或更多的线程,以便每个对象都通过以下方式"迭代":
void ClearThreadLocalData()
{
#pragma omp parallel
{
// assuming data_t has a "clear()" method
GetData().clear();
}
}
有没有更惯用/安全的方式来实施ClearThreadLocalData()
?
您可以为数据创建和使用全局版本号。 每次需要清除现有缓存时,请递增它。 然后修改GetData
以检查版本号(如果存在现有数据对象),丢弃现有数据对象并在过期时创建一个新对象。 (如果可以修改类,则分配的data_t
对象的版本号可以存储在data_t
中,如果不能,则可以存储在第二个线程局部变量中。 你最终会得到类似的东西
static int dataVersion;
data_t& GetData()
{
static data_t *d = NULL;
#pragma omp threadprivate(d); // !!!
if (d && d->myDataVersion != dataVersion) {
delete d;
d = nullptr;
}
if (!d) {
d = new data_t();
d->myDataVersion = dataVersion;
}
return *d;
}
这并不取决于data_t
中是否存在Clear
方法,但是如果您有方法,请将删除和重置替换为对Clear
的调用。 我正在使用d = nullptr
以避免重复调用new data_t()
。
如果要避免全局变量,全局dataVersion
可以是data_t
的静态成员,如有必要,它可以是原子的,尽管GetData
需要更改来处理它。
重置数据时,只需更改全局版本号:
++dataVersion;
相关文章:
- 为什么 beginthreadex 线程参数变量在父线程中没有更新
- C++多线程程序:变量定义为类成员的隔离错误
- 线程局部变量的初始化顺序
- __thread Embarcadero c++ 10.1 中不创建特定于线程的变量
- 访问其他线程堆栈变量如何在C++中工作?
- 在 OpenMP 中重置线程局部变量
- C++14 线程/条件变量误解
- 如何使用C 类的线程成员变量
- 线程局部变量的初始化
- 是包含线程局部变量重入的函数
- 我们是否需要原子地递增线程局部变量
- 最佳多线程全局变量管理
- 如何在c++中初始化线程局部变量
- 模拟线程局部变量
- 作用域和线程局部变量如何在 (V8) C++中工作?
- 线程局部全局作用域变量
- 在运行循环外声明、分配和释放线程局部指针变量
- 如何定义线程局部的局部静态变量
- 通过非线程局部对象访问的线程局部变量
- 是否可以使用与非线程局部变量同名的线程局部变量