c++ - openmp 共享或什么都没有。私有与未初始化
问题描述
这两种openmp实现之间有区别吗?
float dot_prod (float* a, float* b, int N)
{
float sum = 0.0;
#pragma omp parallel for shared(sum)
for (int i = 0; i < N; i++) {
#pragma omp critical
sum += a[i] * b[i];
}
return sum;
}
和相同的代码,但第 4 行没有 shared(sum) 因为 sum 已经初始化?
#pragma omp parallel for
for(int = 0; ....)
openmp中的私有问题相同:
是
void work(float* c, int N)
{
float x, y; int i;
#pragma omp parallel for private(x,y)
for (i = 0; i < N; i++)
{
x = a[i]; y = b[i];
c[i] = x + y;
}
}
与没有 private(x,y) 相同,因为 x 和 y 未初始化?
#pragma omp parallel for
解决方案
这两种openmp实现之间有区别吗?
float dot_prod (float* a, float* b, int N)
{
float sum = 0.0;
# pragma omp parallel for shared(sum)
for (int i = 0; i < N; i++) {
#pragma omp critical
sum += a[i] * b[i];
}
return sum;
}
在 openMP 中,在并行范围之外声明的变量是shared
,除非它被显式呈现private
。因此shared
可以省略声明。
但是您的代码远非最佳。它可以工作,但会比其顺序对应物慢得多,因为critical
将强制顺序处理并且创建关键部分具有重要的时间成本。
正确的实现将使用reduction
.
float dot_prod (float* a, float* b, int N)
{
float sum = 0.0;
# pragma omp parallel for reduction(+:sum)
for (int i = 0; i < N; i++) {
sum += a[i] * b[i];
}
return sum;
}
减少创建一个隐藏的局部变量,以在每个线程中并行累积,并且在线程销毁之前对共享变量执行这些局部和的原子加法sum
。
openmp中的私有问题相同:
void work(float* c, int N)
{
float x, y; int i;
# pragma omp parallel for private(x,y)
for (i = 0; i < N; i++)
{
x = a[i]; y = b[i];
c[i] = x + y;
}
}
默认情况下,x
和y
是共享的。因此,如果没有 private
行为将会有所不同(并且有问题,因为所有线程都将修改相同的全局可访问变量x
并且y
没有原子访问)。
与没有 private(x,y) 相同,因为 x 和 y 未初始化?
初始化x
并不y
重要,重要的是它们在哪里声明。为了确保正确的行为,它们必须是私有的,并且代码将是正确的,x
并且y
在循环中使用之前已设置。
推荐阅读
- php - 如何在 Directadmin 中启用/安装 PHP exif?
- c++ - 无法通过 boost::logger 进行编译
- php - php URL 变量似乎不起作用
- python-3.x - 使用 Python、Selenium 检查两个元素的存在
- javascript - 克隆所选 event.target 的父 div
- javascript - Babel、Dart、TypeScript 和其他 JavaScript 编译器的意义何在?
- javascript - 下拉菜单无法在 React 中实现
- javascript - 如何处理sql查询中的数组值
- python - python请求google.com抛出SSLError
- java - Azure IoTHub DeviceMessage,消息正文上的路由过滤器不起作用