繁体   English   中英

并行或同步遍历巨型数组会更快吗?

[英]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

笔记:

  1. 它假定在​​一次迭代中运行的所有代码都不相互依赖。
  2. 在大多数实际用例中,我们要并行化的代码是IO和CPU的混合。
  3. 很难将IO绑定和CPU绑定分开

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM