并行处理数组索引的最佳方法?

Posted

技术标签:

【中文标题】并行处理数组索引的最佳方法?【英文标题】:Optimal way to handle array indexing in parallel? 【发布时间】:2016-09-17 16:34:37 【问题描述】:

我有以下情况:我有一个大小为 L 的盒子中的粒子列表,其中 L 是其中一个边的长度。

接下来,我将框拆分为单元格,其中 L/cell_dim = 7。所以有 7*7*7 个单元格。

最后,我阅读了所有的粒子,记下它们的位置,并计算出它们在哪个单元格中。


我在 openMP 并行 for 循环中完成上述操作。但是,我需要以线程安全的方式捕获信息,这样我就不必遍历每个单元格的所有粒子。所以我需要一些方法来将粒子的任意子集并行记录到每个单元中。


我现在的方法利用了 OpenMP 关键代码块。我有一个数组大小 [7][7][7][max_particles],其中 max_particles 是每个单元格的最大粒子数,但远小于粒子总数。我在计数器数组大小[7][7][7]中记录添加的最后一个粒子的索引,并根据我的并行循环中的最新计数更新单元数组:

int cube[7][7][7][10];
int cube_counts[7][7][7]=0;

#pragma omp parallel for num_threads(a lot)  
for (int i = 0; i < num_particles; i++)
    cell_x = //cell calculation;
    cell_y = //ditto;
    cell_z = //...;

#pragma omp critical
    
        cube_counts[cell_x][cell_y][cell_z] += 1;

        // for readability 
        int index = cube_counts[cell_x][cell_y][cell_z];

        cube[cell_x][cell_y][cell_z][index] = i;
    


// rest in pseudo code: 

foreach cell: 
    adjacent_cell = cell2

    particle_countA = cube_counts[cellx][celly][cellz]
    particle_countB = cube_counts[cell2x][cell2y][cell2z]

   // these two for loops will cover ~2-4 particles,
   // so super small...as a result of the cell analysis above. 
    for particle in cell:
        for particle in cell2: 
             ...do stuff

虽然这可行,但当我能够消除关键块(我在一个具有 60 个物理、240 个逻辑的英特尔协处理器上)时,它的速度提高了 2 倍以上。

如何在不需要关键块的情况下完成此操作?我想过做一个大数组......但是当我遍历 7*7*7*257(其中 257 是粒子数)数组时,我失去了所有我获得的东西。链表仍然有竞争条件。

也许是某种无序的线程安全列表...?

【问题讨论】:

你不能把粒子分成 N 个任意大小大致相等的集合,其中 N 是物理线程的数量吗? @Cheers 和 hth。 - Alf 我不这么认为......也许:粒子本身不是线程安全的——它们与所有其他粒子交互。所以真的,我只需要知道每个细胞中有哪些粒子......以及有多少。我想我可以拆分它们...然后我将拥有 60*7*7*7 链接列表,我必须将它们堆叠在一起成为 7*7*7 链接列表...它可能会变得非常讨厌...和风拥有相似数量的关键操作... 在 open mp 中,关键块是一个非常重的结构,因为它会锁定整个代码片段。锁可能工作得很好。 @Mehno 哇谢谢伙计!!..不知道锁; def 留下这个,因为我认为可能有其他方法可以解决这个问题.. 【参考方案1】:

使用锁代替临界区可以进一步驱动:

您可以使用编译器将转换为正确的 x86 特定汇编器指令的原子增量和原子赋值伪调用(“内在函数”)。然而,这取决于平台甚至编译器。

如果您使用现代 c++ 编译器 (C++11),那么 std::atomic_* 可能是最好的方法。

【讨论】:

以上是关于并行处理数组索引的最佳方法?的主要内容,如果未能解决你的问题,请参考以下文章

并行执行DynamoDB查询(全局二级索引的BatchGetItems)

并行处理中的最佳内核数是多少?

在 Python 中划分大文件以进行多处理的最佳方法是啥?

javascript async / await - 并行处理数组

java 容易并行处理数组

使用二维并行数组存储数据