使用临时二维数组规避OpenMP数据依赖的方法是否可行?
你的并行化方法核心思路正确,但存在关键代码错误
你的方法通过给每个线程分配独立的累加行,避免了多个线程同时修改同一个vec元素的数据竞争,这个思路是可行的,但代码里有一个致命错误:
错误点:求和方向搞反了
mat是num_thread行、n列的矩阵,每个线程只修改自己行的元素,最终需要对每一列求和(汇总所有线程在同一列的累加值),但你用了rowwise().sum()(对每行求和),这会得到一个维度为num_thread的向量,和vec(n)的维度不匹配,编译会报错,且结果完全错误。正确的写法应该是mat.colwise().sum()。
修正后的并行代码
int n=5; int num_thread = 6; omp_set_num_threads(num_thread); Eigen::MatrixXd mat(num_thread,n); mat.setZero(); #pragma omp parallel for for(int i=0;i<100;i++) { int idx_pool = omp_get_thread_num(); int idx_col = i%n; mat(idx_pool,idx_col)+=(i/n); } Eigen::VectorXd vec(n); vec = mat.colwise().sum(); // 修正为按列求和 std::cout<<vec<<std::endl;
验证正确性
修正后,这段代码的计算逻辑和串行代码完全一致:每个列的累加和对应原串行代码中vec的元素,最终输出的每个值都是190,和串行结果一致。
另外,线程数设置为6是合理的,OpenMP会自动将100次循环迭代分配给6个线程执行,不会影响结果正确性。
内容的提问来源于stack exchange,提问作者Oliver Redman
相关产品推荐
相关产品推荐

