繁体   English   中英

在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()); 
    }
}

现在,我的问题是我需要一个重置数据的函数,即必须考虑创建的每个线程局部对象。

现在,我的解决方案是使用并行区域,希望使用与“parallel for”相同或更多的线程,以便每个对象都“迭代”通过:

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来替换delete-and-reset。 我正在使用d = nullptr来避免重复调用new data_t()

如果要避免全局变量,全局dataVersion可以是dataVersion的静态成员, data_t如果需要它可以是原子的,尽管GetData需要更改来处理它。

当需要重置数据时,只需更改全局版本号:

++dataVersion;

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM