[英]Would it be faster to iterate over a giant array in parallel or synchronously?
给定一个巨大的阵列和一个单核计算机,并行或顺序遍历阵列会更快吗? 假设在迭代过程中没有做任何工作,实际上只是迭代数组。
我的直觉说顺序执行会更快,但是我无法凭借我对操作系统和处理器的了解来证明答案。 似乎无论哪种方式都必须完成相同数量的工作,但是并行执行将为上下文切换带来额外的复杂性。
这个问题的真实世界扩展是javascript的forEach
方法。 本机forEach
同步执行其回调
var a = [1,2,3,4,5,6...100000000000000];
a.foreach(function(number) {
// do computationally expensive, synchronous operation eg lots of additions/multiplications
});
console.log('done iterating through for loop and doing all of the work')
为上述代码使用forEach的异步版本是否会更有利(特别是考虑到js只能使用一个内核)?
如果我们也做同样的问题但使用异步工作,则在发生阻塞操作后,forEach回调将变为异步。
var a = [1,2,3,4,5,6...100000000000000];
a.foreach(function(number) {
// do asynchronous work, eg access to filesystem
$.ajax({
url: 'http://google.com',
success: function() {
console.log('suceeded for ' + number)
})
});
console.log('done iterating through for loop but not with all async operations')
在这种情况下,使用forEach的异步版本会更有利吗? 似乎我们已经通过仅切换IO而不是在启动io之前进行切换而更好地利用了同步版本中的CPU。
只要您使用单个内核,执行某种并行操作就永远没有优势。 正确的是,设置多个任务/线程会给每个任务/线程带来一定的开销。 跨并行操作分时共享单个内核会增加每个任务切换的开销。 顺序迭代没有这种开销。 拥有并行内核的唯一优势就是拥有多个内核。
现代的CPU都是流水线式的,而且大多数都是超标量启动。 但是,尝试某种并行操作不会“打包”或填充超标量单元。 我不知道任何Javascript引擎都能做到这一点。
哦,仅作记录,使用for循环比使用foreach更好。 原因很简单,因为foreach必须在每次通过时都调用一个函数,即使它是一个匿名函数也是如此。 调用函数会产生一定的开销。 在for循环中,函数的内容被内联到循环的主体中,将没有这种开销。 在其他论坛上对此进行了广泛的辩论,但我的经验证明了这一事实。
它完全取决于代码(您提供的代码很高兴)。 因此,第一个问题的答案是“ 否” 。 对于第二个问题, 这取决于 。
如果代码是完整的,CPU绑定在单核计算机上,则同步版本会快一点。 如果有任何IO绑定代码,则异步版本将在同一台计算机上更快。 因为访问IO不会处理CPU。
仅在多核计算机上,如果cpu绑定代码以异步模式运行,它们将运行得更快。 IO绑定代码仍将比其同步姐妹运行速度更快。
这是一张夏日餐桌,
type cpu bound io bound mixed
-------------------------------------------------------------------
single-core synchronous normal slower slower
single-core asynchronous normal faster faster
multi-core synchronous normal slower slower
multi-core asynchronous faster faster faster
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.