在 OpenMP 中重置线程局部变量

Posted

技术标签:

【中文标题】在 OpenMP 中重置线程局部变量【英文标题】:Reset thread-local variables in OpenMP 【发布时间】:2018-05-04 12:45:07 【问题描述】:

我需要一种一致的方式来重置我的程序创建的所有线程局部变量。问题在于线程本地数据是在不同于使用它们的地方创建的。

我的程序大纲如下:

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()

【问题讨论】:

这个方法对我来说很好。 为什么你想这样做? data_t 代表什么以及如何在并行区域之间使用它?为什么突然想清零?你所做的事情听起来很危险……在很多情况下,两个并行区域之间的线程私有变量的生命周期和值是未指定的。 @Zulan data_t 是一个包含计算的lru缓存;这些计算,如果没有预先计算/记忆,对于后续用户的每次计算都会触发数百万次(参见user 函数)。每次发生特定操作时,这些计算都会变得无效,并且必须清除缓存。 【参考方案1】:

您可以为数据创建和使用全局版本号。每次需要清除现有缓存时增加它。然后修改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;

【讨论】:

以上是关于在 OpenMP 中重置线程局部变量的主要内容,如果未能解决你的问题,请参考以下文章

Java中线程局部变量ThreadLocal使用教程及源码分析

内联函数的局部静态/线程局部变量?

多线程访问全局变量和局部变量

线程局部变量

python线程中的全局变量与局部变量

什么是线程局部变量?