【发布时间】:2016-09-28 15:06:16
【问题描述】:
我目前正在尝试提高代码的并行性能,但我还是 OpenMP 的新手。我必须遍历一个大容器,在每次迭代中读取多个条目并将结果写入单个条目。下面是我正在尝试做的一个非常简单的代码示例。
data 是一个指向数组的指针,其中存储了很多数据点。在并行区域之前,我创建了一个数组newData,因此可以将data 用作只读,将newData 用作只写,之后我将旧的data 扔掉并使用newData 进行进一步计算。
据我了解,data 和 newData 在线程之间共享,并且在并行区域内声明的所有内容都是私有的。
多线程读取data会导致性能问题吗?
我正在使用#critical 为newData 的元素分配一个新值以避免竞争条件。这是必要的吗,因为我只访问一次 newData 的每个元素,并且从不通过多个线程访问?
我也不确定日程安排。我是否必须指定是否需要 static 或 dynamic 时间表?我可以使用nowait,因为所有线程都是相互独立的吗?
array *newData = new array;
omp_set_num_threads (threads);
#pragma omp parallel
{
#pragma omp for
for (int i = 0; i < range; i++)
{
double middle = (*data)[i];
double previous = (*data)[i-1];
double next = (*data)[i+1];
double new_value = (previous + middle + next) / 3.0;
#pragma omp critical(assignment)
(*newData)[i] = new_value;
}
}
delete data;
data = newData;
我知道在第一次和最后一次迭代中 previous 和 next 无法从 data 中读取,在实际代码中这已得到处理,但对于这个最小的示例,您会想到读取多个次来自data。
【问题讨论】:
-
作为第一步,始终找出瓶颈,即...(留作练习)
-
你确定这段代码是可并行的吗?如果并行执行代码,则存在无法满足的依赖关系。
-
因为我只使用前一个时间步长 (
data) 中的数据点来计算新时间步长newData中的数据点,所以我看不到任何破坏并行化本身的依赖项。 -
乍一看,代码看起来不错。只需使用
schedule(static)并摆脱critical。并确保在启用最大优化的情况下进行编译。 -
所以
critical不是必需的吗?我不确定。谢谢
标签: c++ multithreading performance openmp