在 OpenMP 中加入数组结果
Join array results in OpenMP
我正在使用OpenMP编写c ++代码。我有一个全局大数组(100,000+ 个元素),将通过在 for 循环中添加值来修改。有没有办法让我有效地让 OpenMP 创建的用于并行的每个线程维护其数组的本地副本,然后在循环后加入?由于线程数是一个变量,因此我无法事先创建数组的本地副本。如果使用全局副本并通过同步锁解决争用条件,则性能很糟糕。
谢谢!
编辑:抱歉不清楚。以下是一些伪代码,希望可以澄清这种情况:
int* huge_array=new int[N];
memset(huge_array, 0, N*sizeof(int));
#pragma omp parallel for
for (i=0; i<n; i++)
{
get a value v independently
get a position p independently
// I have to set a lock here
omp_set_lock(&lock);
huge_array[p] += v;
omp_unset_lock(&lock);
}
有没有办法提高上述代码的性能?
好吧,我终于明白你想做什么了。是的,您的操作方式与 ptreads 相同。
std::vector<int> A(N,0);
std::vector<int*> local(omp_max_num_threads());
#pragma omp parallel
{
int np = omp_get_num_threads();
std::vector<int> localA(N);
local[omp_get_thread_num()] = localA.data();
// add values to local array
#pragma omp for
for(int i=0; i<num_values; ++i)
localA[position()] += value(); // (1)
// implicit barrier ensures all local copies are ready for aggregation
// aggregate local copies into global array
#pragma omp for
for(int k=0; k<N; ++k)
for(int p=0; p<np; ++p)
A[k] += local[p][k]; // (2)
// implicit barrier ensures no local copy is deleted before aggregation is done
}
但重要的是并行进行聚合。
在沃尔特的回答中,我相信而不是
std::vector<int*> local(omp_max_num_threads());
它应该是
std::vector<int*> local(omp_get_max_threads());
omp_max_num_threads()
不是 OpenMP 中的例程。
使用指令怎么样
'#'pragma omp parallel for private(VARIABLE)
对于您的程序(仅带有十字,而不是这些")?
编辑:对于您的代码,我会使用我的指令,在锁定和解锁变量时,您不会浪费太多时间......
编辑2:抱歉,您不能使用我的代码来解决您的问题,只有当您先创建一个临时数组来临时存储数据时......
我所知,您基本上是在填充直方图,其中position
是要填充的直方图的箱,value
是您将添加到该箱中的权重/值。 并行填充直方图等效于执行数组缩减。 OpenMP 的C++实现对此没有直接支持,但是,据我所知,Fortran 实现的某些版本确实如此。 要使用 OpenMP 在C++中减少数组,我有两个建议。
数组)的箱数远小于填充直方图的值数(这通常是首选情况,因为人们希望每个箱中都有合理的统计数据),那么您可以并行填充直方图的私人版本并将它们串行合并到关键部分中。 由于箱的数量远小于值的数量,这应该是有效的。
2.) 但是,如果箱的数量很大(正如您的示例似乎暗示的那样),那么也可以并行合并私有直方图,但这有点棘手。 此外,需要注意缓存对齐和错误共享。
我展示了如何执行这两种方法,并在以下问题中讨论了一些缓存问题:与 openmp 并行填充直方图(数组缩减),而无需使用关键部分。
- C++ 检查结果数组中有多少次数字
- 数组上的相同逻辑会产生不同的结果
- 指针数组中的意外结果
- 使用指针访问数组元素时出现意外结果
- C++数组和指针的大小的结果
- 如何从2D数组为QHeightMapSurfaceDataProxy创建高度图以显示2D傅立叶变换结果
- 如何使用 c++ 将股票代码的结果添加到 poloniex 中的数组中?
- 使用动态分配的数组进行矩阵乘法;结果不正确
- 删除动态数组会弄乱我的结果
- 使用 sizeof 计算数组中的元素数时的结果不同
- 在 Qt 中解析嵌套的 JSON 时出现意外结果(数组不存在)
- 插入指针数组会删除上一个结果
- 二维数组的输出结果
- 为什么我不能将 op 结果乘以常量特征张量数组
- 我写了这个简单的代码,应该计算一系列数组元素的最高数量,但结果很奇怪
- 使用增量/减少操作员在C 中显示数组的奇怪结果
- *char数组到字符串(两次运行代码和两个不同的结果)
- 尝试将二进制数组转换为十六进制C++然后打印结果
- c++中出现意外的数组结果
- 在 OpenMP 中加入数组结果