【问题标题】:Is mutex lock required when each thread is writing to a separate cell in a shared 2d array当每个线程写入共享二维数组中的单独单元时,是否需要互斥锁
【发布时间】:2020-12-09 23:31:37
【问题描述】:

元胞自动机的以下并行计算是否需要互斥锁?

我认为在使用并行线程时写入共享资源时总是建议使用互斥锁。

互斥锁大大减慢了程序的速度,但是否需要它来确保二维数组 (futureOcean) 中的数据保持安全/一致?

当互斥锁在写操作期间锁定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 二维数组,显然代表海洋。

还有一个名为futureOcean 的1000x600 二维数组,它将存储currentGeneration + 1 的每个单元格的状态。

最初ocean 填充有:

  • 50% 水,即 0 值。
  • 25% 的鱼,即正整数值
  • 25% 鲨鱼,即负整数值

处理单代涉及处理ocean中每个单元格的规则。

每次计算当前单元格的新值时,我都会将其未来值存储在第二个二维数组 (futureOcean) 中,在 row/column 的位置,原始值在 ocean 内。所以futureOcean中的每个单元格每一代只会更新一次。

我这样做了 20000 次(几代人)。

【问题讨论】:

    标签: c multithreading parallel-processing cellular-automata


    【解决方案1】:

    如果Ocean 仅在构建新一代期间被读取,则没有潜在的竞争条件并且不需要锁定。多个线程可以毫无问题地从一个常量源读取。

    如果futureOcean 中的每个位置仅更新一次,则该位置没有竞争写入,并且不需要锁定。单个线程可以毫无问题地写入其他线程未触及的唯一位置。

    然后,您必须等待 futureOcean 完全更新后再开始新的生成,以避免在它仍在写入时读取它。

    您可以通过以每个线程写入数组的连续部分的方式拆分工作来提高多线程性能。否则,多个线程可能会写入彼此靠近的位置。如果这发生在一个或两个高速缓存行的距离内(在 x86/64 处理器中为 64 到 128 个字节),那么您可能会反复使该部分内存无效并强制在多个核心高速缓存中重新加载。 (见false sharing

    【讨论】:

    • 确实如此,“ocean 仅在构建新一代期间被读取”,“futureOcean 中的每个位置仅更新一次”和我“等待@987654327 @要在开始新的一代之前完全更新”
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-08-31
    • 2011-08-28
    • 2010-09-12
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多