gpt4 book ai didi

c++ - 为什么 OpenMP 比简单归约的顺序程序慢?

转载 作者:太空宇宙 更新时间:2023-11-03 10:38:25 25 4
gpt4 key购买 nike

我正在尝试查找数组中元素的总和,如下所示。然而,令人惊讶的是,OpenMP 实现比顺序实现慢。我尝试了堆分配数组和堆栈分配数组,得到了相似的结果。任何帮助是极大的赞赏。

#include <iostream>
#include <omp.h>
int main() {
int N = 10000;
int * ary = new int[N];
for (int i = 0; i < N; i++) { input_file >> ary[i]; }
int sum = 0;
clock_t begin = clock();
for (int i = 0; i < N; i++) { sum += ary[i]; }
clock_t end = clock();
cout << sum;
double elapsed_time = double(end - begin) / CLOCKS_PER_SEC;
sum = 0;
begin = clock();
#pragma omp parallel
{
int thread_id = omp_get_thread_num();
int total_threads = omp_get_num_threads();
int elem_per_thread = N / total_threads;
int base = thread_id * elem_per_thread;
int internal_sum = 0;
for (int i = base; i < (base + elem_per_thread); i++) {
internal_sum += ary[i];
}
#pragma omp critical
{
sum += internal_sum;
}
}
end = clock();
cout << sum;
elapsed_time = double(end - begin) / CLOCKS_PER_SEC;
}

顺序程序需要 5e-06 (s) 完成,并行程序需要 0.001733 (s)。我正在使用 g++ -std=c++11 main.cpp -fopenmp -O3 && ./a.out

在 Ubuntu 16.04 上编译

最佳答案

顺序程序优化到什么都不做。这是因为唯一的副作用是 sum 的值,而 sum 的值在您的程序中是不可观察的。

使用 OpenMP,将事物线程化的复杂性会阻止编译器意识到您没有做任何事情。

可以避免这种情况的一种简单方法是添加 return sum; 现在它显示为退出代码,这是可观察的,因此无法优化计算。

现在,编译器仍然可以自由地永远不分配ary,因为它可以证明ary[i]==i 对于所有i,并用 i 替换读取 ary[i],然后在编译时计算 1< 中 i 的总和1000050005000,消除整个循环并使其成为 sum=50005000 并且仍然需要零时间。

关于c++ - 为什么 OpenMP 比简单归约的顺序程序慢?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52840722/

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