c – 在CPU上并行减少阵列
发布时间:2020-12-16 09:40:40 所属栏目:百科 来源:网络整理
导读:有没有办法在C/C++上并行减少CPU上的数组?我最近了解到使用 openmp是不可能的.还有其他选择吗? 解决方法 补充:请注意,您可以按照 here所述的方式使用OpenMP实现“自定义”缩减. 对于C:with 07月份的parallel_reduce(SO标签:tbb),您可以减少复杂类型,如
有没有办法在C/C++上并行减少CPU上的数组?我最近了解到使用
openmp是不可能的.还有其他选择吗?
解决方法
补充:请注意,您可以按照
here所述的方式使用OpenMP实现“自定义”缩减.
对于C:with 07月份的parallel_reduce(SO标签:tbb),您可以减少复杂类型,如数组和结构.虽然与OpenMP的减少条款相比,所需代码的数量可能会大得多. 作为一个例子,让我们并行化矩阵到矢量乘法的简单实现: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个点的加权centroid,其中C是点数组,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],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. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |