c++ - 在允许并行性的情况下用 STL 算法替换 for 循环

标签 c++ c++11 parallel-processing atomic stl-algorithm

我有这个方法:

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

我想使用类似 std::transform 的 STL 算法对其进行重构,主要是为了代码的一致性。 我还有大约五种其他方法,它们是主题的变体,我已经能够使用 std::transform 进行重构。或 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对于我的数组,但它会减慢我不需要原子访问的地方的计算速度吗?

最佳答案

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;
    }
}

请注意,这会执行 data[i] = data[i] + stuff而不是 data[i] += stuff .所以制作data[i] std::atomic<double> 的数组使用此代码不会产生单个原子指令。

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

关于c++ - 在允许并行性的情况下用 STL 算法替换 for 循环,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17852292/

相关文章:

C++ - 具有右值引用的函数模板特化行为

c++ - GCC 因可变参数模板和指向成员函数的指针而失败

python-2.7 - 使用默认调度程序进行 Dask 内存管理

c++ - 如何使用 gnu_parallel 运行多个可执行文件和/或 bash 脚本?

c++ - g++ 找不到标准 header (iostream、字符串等)

c++ - 运算符++ 中的 Int 参数

c++ - 改变类型而不改变位

multithreading - 如何计算多线程进程的总计算时间

将未初始化的局部变量传递给函数时出现 C++ 编译器警告(?)

c++ - SDL_SaveBMP 倒置保存图片