2

我有这个方法:

void A::overlapOut(int pos)
{
    for(unsigned int j = 0; j < size; ++j)
    {
        out[pos+j] += local_arr[j] / scalingFactor;
    }
}

我想使用 STL 算法重构它std::transform,主要是为了代码一致性。我还有大约五种其他方法,它们是主题的变体,我已经能够使用std::transformor进行重构std::copy,如下所示:

void A::nonOverlapOut(int pos)
{
    auto normalize = [&] (double x) { return x / otherScalingFactor; };
    std::transform(local_arr, local_arr + size, out + pos, normalize);
}

但是,这里的主要区别在于+=. 我的所有其他函数不重叠,并且不使用先前的值,data[i]因此可以进行并行调用,但是这个需要做data[i] += stuff,而不是data[i] = stuff,并且data[i]可能被其他线程访问,他们也会做+=

那么,最好的 C++11-ic 方法是什么?我考虑过使用std::atomic<double>而不是double用于我的数组,但它会减慢我不需要原子访问的地方的计算吗?

4

1 回答 1

0

std::transform可以采用两个输入范围,并且输出迭代器可能与输入相同。

#include <iostream>
#include <algorithm>

int main() {
    double local_arr[] = {9.0, 8.0, 5.0, 4.0, 5.0};
    double out[] = {12.0, 24.0, 36.0, 48.0, 60.0, 72.0, 84.0};
    auto scalingFactor = 7.0;

    size_t size = 5;
    size_t pos = 1;

    std::transform(local_arr, local_arr + size, out + pos, out + pos,
                    [=](double a, double b) { return a / scalingFactor + b; });

    for (auto v : out) {
        std::cout << v << std::endl;
    }
}

请注意,这是 adata[i] = data[i] + stuff而不是data[i] += stuff。因此data[i],使用此代码创建一个数组std::atomic<double>不会产生单个原子指令。

但是在您的情况下,不同的线程写入数组的不相交部分,因此没有冲突(§1.10/4),因此没有数据竞争(§1.10/21),因此线程安全,不需要原子或锁。

于 2013-10-09T19:58:18.560 回答