并行求和一个数组
Posted
技术标签:
【中文标题】并行求和一个数组【英文标题】:Summing up an array in parallel 【发布时间】:2016-09-15 20:35:25 【问题描述】:我有以下算法对数组元素求和:
// global
index = 0
array = [...]
total_sum = 0 // this is what we're interested in
// per thread
thread_sum = 0
mutex.lock()
while (index < array.size)
mutex.unlock()
thread_sum += array[index]
mutex.lock()
index++
total_sum += thread_sum
mutex.unlock()
每个线程都运行相同的代码,并在完成后立即加入主线程。问题是有时不止一个线程添加相同的数字。这是怎么发生的?
原始代码是 C++ 并使用 std::vector/thread/mutex/ref。
【问题讨论】:
完全不要使用线程。你正在扼杀表演。并且每个元素的锁定只会让它变得更糟。 那么,你想用多个线程对单个数组的所有元素求和吗? 【参考方案1】:在释放锁之前增加index
,否则多个线程可能看到相同的值:
// per thread
thread_sum = 0
mutex.lock()
while (index < array.size)
i = index++
mutex.unlock()
thread_sum += array[i]
mutex.lock()
total_sum += thread_sum
mutex.unlock()
再一次,如果您使用atomic integers,原子地更改整数的值可以更有效地完成。
最后考虑在单个工作负载很小或非常可预测时进行批处理,以减少同步的开销。
【讨论】:
我在重新锁定后增加索引。这还不够好吗?有什么区别? 在循环体内部的线程重新加锁之前,另一个线程可能会获得锁并以相同的值进入循环体。以上是关于并行求和一个数组的主要内容,如果未能解决你的问题,请参考以下文章
C++ Armadillo 和 OpenMp:外积求和的并行化 - 定义 Armadillo 矩阵的约简