我试图在单台机器上使用多个线程来查找浮点值数组的平均值。我不关心数组的大小或内存限制(假设一个中等大小的数组,大到足以保证多个线程)。特别是,我正在寻找最有效的调度算法。在我看来,静态块方法将是最有效的。
因此,鉴于我有 x 个机器核心,将数组分块为 array.size/x 值并让每个核心对它们各自的数组块的结果求和似乎是合理的。然后,将每个核心的总和结果相加,最终结果是这个值除以数组元素的总数(注意:在数组元素的 # 不能被 x 整除的情况下,我知道优化在线程中尽可能均匀地分布元素)。
该数组显然将在线程之间共享,但由于不涉及写入,我不需要涉及任何锁定机制或担心同步问题。
我的问题是:这实际上是解决这个问题的最有效方法吗?
相反,例如,考虑静态交错方法。在这种情况下,如果我有四个核心(线程),那么线程一将对数组元素 0、4、8、12 进行操作……而线程二将对元素 1、5、9、13 进行操作……这将看起来更糟,因为每个核心都会不断地获得缓存未命中,而静态块方法意味着每个核心都在成功值上运行并利用数据局部性。我运行的一些测试似乎支持这一点。
那么,谁能指出比静态块更好的方法,或者确认这很可能是最好的方法?
编辑:
我正在使用 Java 和 Linux (Ubuntu)。我尽量不要过多考虑所涉及的语言/平台,而只是从调度的角度抽象地看待问题,涉及手动将工作负载分配给多个线程。但我知道语言和平台是重要因素。
编辑2:
这里有一些时间(纳米时间/ 1000)具有不同的数组大小(双打)。
顺序计时使用单个 java 线程。其他人使用并行工作的所有可用 (4) 内核实现了各自的调度策略。
百万元素:
---连续
5765
1642
1565
1485
1444
1511
1446
1448
1465
1443
---静块
15857
4571
1489
1529
1547
1496
1445
1415
1452
1661
---静态交错
9692
4578
3071
7204
5312
2298
4518
2427
1874
年1900
50000000个元素:
---顺序
73757
69280
70255
78510
74520
69001
69593
69586
69399
69665
---静块
62827
52705
55393
53843
57408
56276
56083
57366
57081
57787
---静态交错
179592
306106
239443
145630
171871
303050
233730
141827
162240
292421