【问题标题】:Speed of Promisified Web WorkersPromised Web Workers 的速度
【发布时间】:2019-06-22 19:23:57
【问题描述】:

我需要多次 (>10,000) 次计算数学密集型函数。我想我会使用网络工作者来减少计算时间。

我正在使用一个函数,它创建一个函数的 blob,将其执行包装在一个 Promise 中,并在该 blob 处运行 web worker。我对其进行了测试,它可以工作,但运行速度比单线程方法慢得多。

单线程:3 毫秒 多线程:5524 毫秒

包含时间测试的完整代码:

https://codepen.io/zakerytclarke/pen/BgRyBm?editors=0012

此代码计算前 n 个方格并将它们推送到一个数组中。控制台分别显示了运行单线程和多线程的时间。

这是我用来承诺网络工作者的功能。是不是有什么问题导致执行时间远远超过一个简单的 for 循环?

function thread(fn){
  return function(args){
    return new Promise(function(resolve) {

        var worker=new Worker(URL.createObjectURL(new Blob(['('+fn+')('+JSON.stringify(args)+')'])));
        worker.postMessage(args)
        worker.onmessage = function(event){
            resolve(event.data);
            worker.terminate();
        };
    });
  }
 }

感谢您的帮助。

这是我的 CPU 上的信息,以防万一:

uinfo 
processor   : 0
vendor_id   : GenuineIntel
cpu family  : 6
model       : 76
model name  : Intel(R) Atom(TM) x7-Z8700  CPU @ 1.60GHz
stepping    : 3
microcode   : 0x367
cpu MHz     : 901.401
cache size  : 1024 KB
physical id : 0
siblings    : 4
core id     : 0
cpu cores   : 4
apicid      : 0
initial apicid  : 0
fpu     : yes
fpu_exception   : yes
cpuid level : 11
wp      : yes
flags       : fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush dts acpi mmx fxsr sse sse2 ss ht tm pbe syscall nx rdtscp lm constant_tsc arch_perfmon pebs bts rep_good nopl xtopology tsc_reliable nonstop_tsc cpuid aperfmperf tsc_known_freq pni pclmulqdq dtes64 monitor ds_cpl vmx est tm2 ssse3 cx16 xtpr pdcm sse4_1 sse4_2 movbe popcnt tsc_deadline_timer aes rdrand lahf_lm 3dnowprefetch epb pti ibrs ibpb stibp tpr_shadow vnmi flexpriority ept vpid tsc_adjust smep erms dtherm ida arat
bugs        : cpu_meltdown spectre_v1 spectre_v2
bogomips    : 3200.00
clflush size    : 64
cache_alignment : 64
address sizes   : 36 bits physical, 48 bits virtual
power management:

processor  : 1
vendor_id   : GenuineIntel
cpu family  : 6
model       : 76
model name  : Intel(R) Atom(TM) x7-Z8700  CPU @ 1.60GHz
stepping    : 3
microcode   : 0x367
cpu MHz     : 875.272
cache size  : 1024 KB
physical id : 0
siblings    : 4
core id     : 1
cpu cores   : 4
apicid      : 2
initial apicid  : 2
fpu     : yes
fpu_exception   : yes
cpuid level : 11
wp      : yes
flags       : fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush dts acpi mmx fxsr sse sse2 ss ht tm pbe syscall nx rdtscp lm constant_tsc arch_perfmon pebs bts rep_good nopl xtopology tsc_reliable nonstop_tsc cpuid aperfmperf tsc_known_freq pni pclmulqdq dtes64 monitor ds_cpl vmx est tm2 ssse3 cx16 xtpr pdcm sse4_1 sse4_2 movbe popcnt tsc_deadline_timer aes rdrand lahf_lm 3dnowprefetch epb pti ibrs ibpb stibp tpr_shadow vnmi flexpriority ept vpid tsc_adjust smep erms dtherm ida arat
bugs        : cpu_meltdown spectre_v1 spectre_v2
bogomips    : 3200.00
clflush size    : 64
cache_alignment : 64
address sizes   : 36 bits physical, 48 bits virtual
power management:

 processor : 2
vendor_id   : GenuineIntel
cpu family  : 6
model       : 76
model name  : Intel(R) Atom(TM) x7-Z8700  CPU @ 1.60GHz
stepping    : 3
microcode   : 0x367
cpu MHz     : 860.525
cache size  : 1024 KB
physical id : 0
siblings    : 4
core id     : 2
cpu cores   : 4
apicid      : 4
initial apicid  : 4
fpu     : yes
fpu_exception   : yes
cpuid level : 11
wp      : yes
flags       : fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush dts acpi mmx fxsr sse sse2 ss ht tm pbe syscall nx rdtscp lm constant_tsc arch_perfmon pebs bts rep_good nopl xtopology tsc_reliable nonstop_tsc cpuid aperfmperf tsc_known_freq pni pclmulqdq dtes64 monitor ds_cpl vmx est tm2 ssse3 cx16 xtpr pdcm sse4_1 sse4_2 movbe popcnt tsc_deadline_timer aes rdrand lahf_lm 3dnowprefetch epb pti ibrs ibpb stibp tpr_shadow vnmi flexpriority ept vpid tsc_adjust smep erms dtherm ida arat
bugs        : cpu_meltdown spectre_v1 spectre_v2
bogomips    : 3200.00
clflush size    : 64
cache_alignment : 64
address sizes   : 36 bits physical, 48 bits virtual
power management:

processor  : 3
vendor_id   : GenuineIntel
cpu family  : 6
model       : 76
model name  : Intel(R) Atom(TM) x7-Z8700  CPU @ 1.60GHz
stepping    : 3
microcode   : 0x367
cpu MHz     : 557.593
cache size  : 1024 KB
physical id : 0
siblings    : 4
core id     : 3
cpu cores   : 4
apicid      : 6
initial apicid  : 6
fpu     : yes
fpu_exception   : yes
cpuid level : 11
wp      : yes
flags       : fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush dts acpi mmx fxsr sse sse2 ss ht tm pbe syscall nx rdtscp lm constant_tsc arch_perfmon pebs bts rep_good nopl xtopology tsc_reliable nonstop_tsc cpuid aperfmperf tsc_known_freq pni pclmulqdq dtes64 monitor ds_cpl vmx est tm2 ssse3 cx16 xtpr pdcm sse4_1 sse4_2 movbe popcnt tsc_deadline_timer aes rdrand lahf_lm 3dnowprefetch epb pti ibrs ibpb stibp tpr_shadow vnmi flexpriority ept vpid tsc_adjust smep erms dtherm ida arat
bugs        : cpu_meltdown spectre_v1 spectre_v2
bogomips    : 3200.00
clflush size    : 64
cache_alignment : 64
address sizes   : 36 bits physical, 48 bits virtual
power management:```

【问题讨论】:

  • 您的数学密集型函数是否需要 10k 次迭代?如果是这种情况,那么 10k 循环对于 JS 执行来说并不密集。为什么它在 Web Worker 中执行缓慢是因为 Web Worker 可能需要时间才能产生。如果你真的想测试使用 web Worker 和单线程的多线程之间的性能,请尝试运行一个迭代次数超过 500 万次的 for 循环(这对 JS 来说是密集的),然后看看游戏如何变化
  • 你已经在你的论文中证明了至少两个事实:1)这:i*i 不等于 createObjectURL() 然后instantiate a Blob 然后JSON.stringify() 然后create function object in the Worker 然后execute the function in the worker。并且 2) 工人不适合简单的函数,例如平方数字。
  • 另外,如前所述,您的时间测量考虑了将结果记录到控制台所需的时间。作为一个实验,删除控制台日志。我敢打赌单线程版本会达到零毫秒。

标签: javascript multithreading web-worker


【解决方案1】:

您忽略了网络工作者的严重开销。难怪您的代码通过对函数进行字符串化来创建 blob,从该文件创建一个工作器,解析工作器的代码,实例化一个承诺,发送一条消息,设置一个侦听器,并异步等待来自工作器的结果,比做两个双打的单次乘法慢几千倍。事实上,我很惊讶你甚至能在 5 秒内产生 10000 个工人。

This benchmark 估计设置一个工人大约需要 40 毫秒。所以不,工人不是你应该为任何事情产生的轻量级线程。它们被视为工作线程,您应该向它们发送(许多)消息以进行处理和响应。您可能希望创建一个工作池以将负载分散到多个线程。

当然,对于您的square 函数,这些都不适用。它太小了——它只做一次乘法。在主线程上执行此操作将比与另一个线程通信的任何操作更快。如果您在该函数中有一个 100000 项循环,那么在后台线程中运行可能会变得值得。你所达到的 3ms 单线程性能甚至不会明显阻塞主线程。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-12-06
    • 2014-10-01
    • 2013-06-05
    • 1970-01-01
    • 2012-07-07
    相关资源
    最近更新 更多