c - 这是C中“限制”的正确使用吗?
问题描述
目前我正在学习并行编程。我有以下需要并行化的循环。
for(i=0; i<n/2; i++)
a[i] = a[i+1] + a[2*i]
如果我按顺序运行它没有问题,但如果我想并行运行它,就会发生数据重复。为避免这种情况,我想将要“读取”的信息存储在单独的变量中,例如 b。
那么代码将是:
b = a;
#pragma omp parallel for private(i)
for(i=0; i<n/2; i++)
a[i] = b[i+1] + b[2*i];
但这里是我开始怀疑的部分。可能变量 b 将指向与 a 相同的内存位置。所以第二个代码块将与第一个代码块完全一样。包括我试图避免的复发。
我用 * retric {variable} 尝试了一些东西。不幸的是,我真的找不到正确的文档。
我的问题:
我是否可以通过如下编写代码来避免数据重复?
int *restrict b;
int *restrict a;
b = a;
#pragma omp parallel for private(i)
for(i=0; i<n/2; i++)
a[i] = b[i+1] + b[2*i];
如果不是,那么实现这一目标的正确方法是什么?
谢谢, 特尔
解决方案
在您提出的代码中:
int *restrict b;
int *restrict a;
b = a;
a
to的分配b
违反了restrict
要求。这需要a
并且b
不指向相同的内存,但它们显然确实指向相同的内存。这是不安全的。
为了安全起见,您必须制作一个单独分配的数组副本。你可以这样做:
int *b = malloc(n * size of(*b));
…error check…;
memmove(b, a, n *sizeof(*b));
…revised loop using a and b…
free(b);
我总是使用memmove()
它,因为它总是正确的,处理重叠的副本。在这种情况下,使用它是合法的,memcpy()
因为分配的空间b
将与空间分开a
。如果新分配的空间完全b
重叠,则系统将被破坏a
,假设指针a
有效。如果有重叠,问题就在于a
分配和释放——a
一个指向已释放内存的悬空指针也是如此(根本不应该被使用),并且b
巧合地分配在a
以前分配旧内存的地方。总的来说,这不是一个值得担心的问题。(使用memmove()
没有帮助,如果a
是一个悬空指针,但如果给定有效指针,它总是安全的,即使内存区域重叠。)
推荐阅读
- c# - UWP 中的 Xamarin Forms MasterDetailPage 按钮填充问题
- c++ - 在 Rcpp 中使用多参数目标函数调用 numDeriv:hessian()
- c - 了解 sprintf 如何将整数转换为字符串
- android - Android - 在 UI 线程上同步调用线程
- d3.js - 在 WebWorker 中使用 D3 (v3) 绘制图形
- javascript - Javascript 练习
- sql - ORACLE 12c 唯一约束在 MERGE 命令中失败,该命令匹配索引中的所有列
- variables - 在 Ansible 中将一个变量分配给当前列表/文件中的另一个变量
- video-streaming - 可以在服务器端使用 WebRTC 来获取流帧吗?
- java - SSO 的泽西岛身份验证