当每个线程写入共享二维数组中的单独单元格时是否需要互斥锁
Is mutex lock required when each thread is writing to a separate cell in a shared 2d array
下面的元胞自动机并行计算是否需要互斥量?
我认为在使用并行线程写入共享资源时总是建议使用互斥锁。
互斥使程序速度显着变慢,但是否需要它以确保二维数组 (futureOcean
) 中的数据保持 safe/consistent?
当互斥体在写入操作期间锁定 futureOcean
时:
2 threads: 163.352990 seconds
5 threads: 515.739237 seconds
10threads: 1021.035517 seconds
不使用互斥体:
2 threads: 65.817534 seconds
10threads: 93.822217 seconds
我正在实施元胞自动机模型,特别是鱼、鲨鱼和海洋模拟。
我有一个名为 ocean
的 1000x600 二维数组,显然代表海洋。
还有另一个 1000x600 的二维数组 futureOcean
,它将存储 currentGeneration + 1
的每个单元格的状态。
最初 ocean
填充了:
- 50% 水,即 0 值。
- 25% 鱼即正整数值
- 25% 鲨鱼即负整数值
处理单代涉及 ocean
.
中每个单元格的处理规则
每次我计算当前单元格的新值时,我将其未来值存储在第二个二维数组 (futureOcean) 中,与原始值相同的 row
/column
位置在 ocean
里面。因此 futureOcean
中的每个单元格每代只会更新一次。
我这样做了 20000 次(几代人)。
如果 Ocean
仅在构建新一代时被读取,则没有潜在的竞争条件,也不需要锁。多个线程可以毫无问题地从常量源读取。
如果 futureOcean
中的每个位置仅更新一次,则该位置没有竞争写入,也不需要锁定。单个线程可以毫无问题地写入其他线程未触及的唯一位置。
然后,您必须等待 futureOcean
在开始新的生成之前完全更新,以避免在它仍在写入时读取它。
您可以通过将工作拆分为每个线程都写入数组的连续部分来提高多线程性能。否则,多个线程可能会写入彼此靠近的位置。如果这种情况发生在一个或两个缓存行的距离内(在 x86/64 处理器中为 64 到 128 字节),那么您可能会反复使该内存部分无效并强制在多个核心缓存中重新加载。 (参见 false sharing)
下面的元胞自动机并行计算是否需要互斥量?
我认为在使用并行线程写入共享资源时总是建议使用互斥锁。
互斥使程序速度显着变慢,但是否需要它以确保二维数组 (futureOcean
) 中的数据保持 safe/consistent?
当互斥体在写入操作期间锁定 futureOcean
时:
2 threads: 163.352990 seconds
5 threads: 515.739237 seconds
10threads: 1021.035517 seconds
不使用互斥体:
2 threads: 65.817534 seconds
10threads: 93.822217 seconds
我正在实施元胞自动机模型,特别是鱼、鲨鱼和海洋模拟。
我有一个名为 ocean
的 1000x600 二维数组,显然代表海洋。
还有另一个 1000x600 的二维数组 futureOcean
,它将存储 currentGeneration + 1
的每个单元格的状态。
最初 ocean
填充了:
- 50% 水,即 0 值。
- 25% 鱼即正整数值
- 25% 鲨鱼即负整数值
处理单代涉及 ocean
.
每次我计算当前单元格的新值时,我将其未来值存储在第二个二维数组 (futureOcean) 中,与原始值相同的 row
/column
位置在 ocean
里面。因此 futureOcean
中的每个单元格每代只会更新一次。
我这样做了 20000 次(几代人)。
如果 Ocean
仅在构建新一代时被读取,则没有潜在的竞争条件,也不需要锁。多个线程可以毫无问题地从常量源读取。
如果 futureOcean
中的每个位置仅更新一次,则该位置没有竞争写入,也不需要锁定。单个线程可以毫无问题地写入其他线程未触及的唯一位置。
然后,您必须等待 futureOcean
在开始新的生成之前完全更新,以避免在它仍在写入时读取它。
您可以通过将工作拆分为每个线程都写入数组的连续部分来提高多线程性能。否则,多个线程可能会写入彼此靠近的位置。如果这种情况发生在一个或两个缓存行的距离内(在 x86/64 处理器中为 64 到 128 字节),那么您可能会反复使该内存部分无效并强制在多个核心缓存中重新加载。 (参见 false sharing)