Visual Studio C++从并行循环中记录日志

v8wbuo2f  于 2023-10-23  发布在  其他
关注(0)|答案(1)|浏览(134)

我有一个并行的循环和一次循环我想记录一些细节。

first_iteration = true;

#pragma omp parallel for schedule(runtime) 
for (int j = 0; j < items.size(); j++) {

    if (first_iteration) {
        FILE_LOG(logINFO) << "blablabla";
        first_iteration = false;
    }

    // do something
}

但是它总是被记录多次(可能是线程次数)。我怀疑它会时不时地抛出一个分段错误。我已经读取了一个可能的solution,带有临时变量和#pragma omp atomic readwrite。但它似乎不适用于Visual Studio 19(cstd14):
错误C3005:“read”:在OpenMP“atomic”指令“上遇到意外标记。
我也需要它在g
11.3.0中工作。

bfhwhh0e

bfhwhh0e1#

如果你想坚持使用OpenMP原子,试试这个。它使用test and test-and-set逻辑来避免缓存线反弹和不必要的同步开销。

int main()
{
    int iteration = 0;

#   pragma omp parallel for
    for(int j = 0; j < 100; j++) {
        int own_iteration;
#       pragma omp atomic read relaxed
        own_iteration = iteration;
        if(own_iteration == 0) {
#           pragma omp atomic update relaxed capture
            own_iteration = iteration += 1;
            if(own_iteration == 1)
                std::cout << "blablabla\n";
        }
    }
}

你可以用C++-11 atomics使代码更简单。

#include <atomic>

int main()
{
    std::atomic<bool> first_iteration = true;

#   pragma omp parallel for
    for(int j = 0; j < 100; j++) {
        if(first_iteration.load(std::memory_order_relaxed)
                && first_iteration.exchange(false, std::memory_order_relaxed)) {
            std::cout << "blablabla\n";
        }
    }
}

当然,在完全并行执行中,“第一次迭代”并不意味着什么。你也可以检查if(j == 0)并完成它。

相关问题