- android - 多次调用 OnPrimaryClipChangedListener
- android - 无法更新 RecyclerView 中的 TextView 字段
- android.database.CursorIndexOutOfBoundsException : Index 0 requested, 光标大小为 0
- android - 使用 AppCompat 时,我们是否需要明确指定其 UI 组件(Spinner、EditText)颜色
我想计算一个二维 float 组 'Image2D' 并通过使用 'OpenMP' 在 中执行外部 for 循环来更快地执行此操作并行。
在循环中,计算“Image2D”内的位置“[jy][jx]”。因此,有可能在同一时刻,两个(或更多)线程想要在相同位置 '[jy][jx]' 增加'Image2D' .根据我的理解(但您可能会更正我),在那种情况下只执行一个增量而另一个增量丢失。
为了避免这种情况,我想添加一行代码“#pragma omp critical”。它确保只有一个线程可以读取/递增/写入变量“Image2D”。
不幸的是,这意味着当第一个线程正在访问“Image2D”时,其他线程必须等待,直到第一个线程完成其工作。对于我的代码,这将极大地减慢执行速度,因为一直在访问“Image2D”。
此外,“#pragma omp critical”过于严格:它阻止多个线程访问整个数组“Image2D”,而它足以阻止访问“Image2D”的一个元素(即一个位置“Image2D[jy][jx]”)。
所以,我的问题是:有没有办法 (i) 防止多个线程同时写入 'Image2D[jy][jx]';(ii) 不让线程不必要地相互等待,从而获得快速代码。
谢谢你的回答
#pragma omp parallel private( ia, iR, Cte, jjx, jx,jy )
{ // start parallel
#pragma omp for
for ( ia = i0a; ia <= i1a; ia++ ) {
// ... code removed ....
for ( iR = i0R; iR <= i1R; iR++ ) {
// ... code removed ....
// 'Cte' (float) and 'jjx' (float) are computed
for ( jy = j0y; jy <= j1y; jy++ ) {
// ... code removed ...
// 'jx' (int) gets computed
#pragma omp critical
Image2D[jy][jx] += Cte * ( 1.0 - ( jjx - jx ) ); // increment 'Image2D[jy][jx]'
// ... code removed ....
} // Next 'jy'
} // Next 'iR'
}// Next 'ia'
}// end parallel section
最佳答案
我不了解 OpenMP,但听起来它并没有给您提供您想要的控制级别。
正如 PetrH 所建议的那样,最好的答案可能是每个线程都有一个私有(private)数组,然后再对这些数组求和。即使这样也可以并行化。
如果您有足够的内存力,那将非常有效。如果不是,您可能需要考虑替代方案。这可能涉及互斥信号量。
显然,您的 2D 阵列足够大,需要 OpenMP,因此每个单元格的互斥体可能会造成浪费。您可以每行有一个互斥锁,或者每 10 行有一个互斥锁,等等。互斥锁越少,两个线程争用同一组单元格的机会就越大。此外,虽然您会在每次循环迭代中获取和提供互斥量一次(并计算哪个互斥量),但如今的操作系统付出了很多努力来快速进行互斥量信号量系统调用。可能是每个线程多一点 CPU 时间可以为您提供所需的调度,因此整体 yield 可能不错。
关于c - 防止多个线程只访问数组的一个元素(而不是整个数组),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30035580/
我是一名优秀的程序员,十分优秀!