【发布时间】: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