Web Worker 比本地线程更重还是更轻
Is web worker heavier or lighter than a native thread
Web Worker 是否只是浏览器创建的普通本机线程 运行 并通过消息队列与其他浏览器线程通信?还是创建的时候不包含其他东西?
我正在查看 emscripten 中的 experimental support of pthread,C++ 中的多线程将在编译后转换为 web worker。但它是否具有与本机代码相同的性能水平?毕竟细粒度多线程是 C++ 中的一个关键特性。
目前,WebWorker 相当重量级,因为 VM 复制了一堆内部状态(有时甚至为 worker 重新编写 JIT 代码)。该状态 比本机线程的几个 MiB 初始堆栈 space 和关联状态大 很多。
其中一些可以通过实现来解决,我预计如果 SharedArrayBuffer or WebAssembly + threads 变得流行,那么浏览器引擎将想要优化一些东西。
话虽如此,您问题的结尾暗示了对线程开销的误解,以及 SharedArrayBuffer 的提案(Emscripten 依赖它来支持 pthreads)是如何工作的。 WebWorkers 目前很重,但它们可以通过 SAB 进行通信,其方式与本机代码(如 C++)完全相同:通过访问完全相同的内存,在相同的虚拟地址。 SAB 向 JavaScript 添加了一种新的 ArrayBuffer,当您 postMessage
将它交给另一个工作人员时,它不会被绝育。当您使用 std::atomic
.
时,多个工作人员可以以与 C++ 代码完全相同的方式查看其他工作人员对缓冲区的更新
同时,根据定义,worker 不能阻塞主线程,因此更有 "native" 的感觉。某些 Web API 并非对所有工作人员都可用,但这种情况一直在发生变化。如果您例如编写游戏并在不同线程中进行网络/音频/渲染/AI/输入。网络正在慢慢找到自己做这些事情的方式。
细节有点棘手
SAB 目前仅支持非原子访问和顺序一致的访问(即目前唯一可用的 Atomic
访问与 C++ 的 std::memory_order_seq_cst
相同)。进行非原子访问应该与 C++ 的非原子访问一样高效(这里我不会涉及大的编译器警告),并且使用 Atomic
应该与 C++ 的 std::atomic
默认一样高效(即 std::memory_order_seq_cst
)。 C++ 有 5 个 SAB 目前不支持的其他内存顺序(relaxed
、consume
、acquire
、release
、acq_rel
)。这些其他内存顺序允许本机代码在某些情况下更快,但更难正确和可移植地使用。它们可能会添加到 SAB 的未来更新中,例如通过 this issue.
SAB 还支持 Futex
本机程序在幕后依赖它来实现高效 mutex
。
与 C++ 相比,还有更棘手的细节,I've detailed some of them 但还有更多。
Web Worker 是否只是浏览器创建的普通本机线程 运行 并通过消息队列与其他浏览器线程通信?还是创建的时候不包含其他东西?
我正在查看 emscripten 中的 experimental support of pthread,C++ 中的多线程将在编译后转换为 web worker。但它是否具有与本机代码相同的性能水平?毕竟细粒度多线程是 C++ 中的一个关键特性。
目前,WebWorker 相当重量级,因为 VM 复制了一堆内部状态(有时甚至为 worker 重新编写 JIT 代码)。该状态 比本机线程的几个 MiB 初始堆栈 space 和关联状态大 很多。
其中一些可以通过实现来解决,我预计如果 SharedArrayBuffer or WebAssembly + threads 变得流行,那么浏览器引擎将想要优化一些东西。
话虽如此,您问题的结尾暗示了对线程开销的误解,以及 SharedArrayBuffer 的提案(Emscripten 依赖它来支持 pthreads)是如何工作的。 WebWorkers 目前很重,但它们可以通过 SAB 进行通信,其方式与本机代码(如 C++)完全相同:通过访问完全相同的内存,在相同的虚拟地址。 SAB 向 JavaScript 添加了一种新的 ArrayBuffer,当您 postMessage
将它交给另一个工作人员时,它不会被绝育。当您使用 std::atomic
.
同时,根据定义,worker 不能阻塞主线程,因此更有 "native" 的感觉。某些 Web API 并非对所有工作人员都可用,但这种情况一直在发生变化。如果您例如编写游戏并在不同线程中进行网络/音频/渲染/AI/输入。网络正在慢慢找到自己做这些事情的方式。
细节有点棘手
SAB 目前仅支持非原子访问和顺序一致的访问(即目前唯一可用的 Atomic
访问与 C++ 的 std::memory_order_seq_cst
相同)。进行非原子访问应该与 C++ 的非原子访问一样高效(这里我不会涉及大的编译器警告),并且使用 Atomic
应该与 C++ 的 std::atomic
默认一样高效(即 std::memory_order_seq_cst
)。 C++ 有 5 个 SAB 目前不支持的其他内存顺序(relaxed
、consume
、acquire
、release
、acq_rel
)。这些其他内存顺序允许本机代码在某些情况下更快,但更难正确和可移植地使用。它们可能会添加到 SAB 的未来更新中,例如通过 this issue.
SAB 还支持 Futex
本机程序在幕后依赖它来实现高效 mutex
。
与 C++ 相比,还有更棘手的细节,I've detailed some of them 但还有更多。