gpt4 book ai didi

c++ - 在 CPU 上并行减少数组

转载 作者:太空狗 更新时间:2023-10-29 20:16:30 26 4
gpt4 key购买 nike

有没有办法在 C/C++ 的 CPU 上并行缩减数组?我最近了解到不可能使用 openmp .还有其他选择吗?

最佳答案

已添加:请注意,您可以按照描述的方式使用 OpenMP 实现“自定义”缩减 here .


对于 C++:在 Intel's TBB 中使用 parallel_reduce (SO 标签:),你可以对数组和结构等复杂类型进行归约。尽管与 OpenMP 的缩减条款相比,所需的代码量可能要大得多。

例如,让我们并行化矩阵到 vector 乘法的简单实现:y=Cx。串行代码由两个循环组成:

double x[N], y[M], C[N][M];
// assume x and C are initialized, and y consists of zeros
for(int i=0; i<N; ++i)
for(int j=0; j<M; ++j)
y[j] += C[i][j]*x[i];

通常,为了使其并行化,交换循环以使外部循环迭代独立并并行处理它们:

#pragma omp parallel for
for(int j=0; j<M; ++j)
for(int i=0; i<N; ++i)
y[j] += C[i][j]*x[i];

然而,这并不总是好主意。如果 M 很小而 N 很大,交换循环将无法提供足够的并行性(例如,考虑计算 M 维空间中 N 个点的加权 centroidC 是点数组,x 是权重数组)。因此,减少数组(即一个点)会有所帮助。以下是使用 TBB 可以完成的操作(抱歉,代码未经过测试,可能会出错):

struct reduce_body {
double y_[M]; // accumulating vector
double (& C_)[N][M]; // reference to a matrix
double (& x_)[N]; // reference to a vector

reduce_body( double (&C)[N][M], double (&x)[N] ) : C_(C), x_(x) {
for (int j=0; j<M; ++j) y_[j] = 0.0; // prepare for accumulation
}
// splitting constructor required by TBB
reduce_body( reduce_body& rb, tbb::split ) : C_(rb.C_), x_(rb.x_) {
for (int j=0; j<M; ++j) y_[j] = 0.0;
}
// the main computation method
void operator()(const tbb::blocked_range<int>& r) {
// closely resembles the original serial loop
for (int i=r.begin(); i<r.end(); ++i) // iterates over a subrange in [0,N)
for (int j=0; j<M; ++j)
y_[j] += C_[i][j]*x_[i];
}
// the method to reduce computations accumulated in two bodies
void join( reduce_body& rb ) {
for (int j=0; j<M; ++j) y_[j] += rb.y_[j];
}
};
double x[N], y[M], C[N][M];
...
reduce_body body(C, x);
tbb::parallel_reduce(tbb::blocked_range<int>(0,N), body);
for (int j=0; j<M; ++j)
y[j] = body.y_[j]; // copy to the destination array

免责声明:我隶属于 TBB。

关于c++ - 在 CPU 上并行减少数组,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9399929/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com