gpt4 book ai didi

Javascript将SharedArrayBuffer同步到主线程

转载 作者:行者123 更新时间:2023-11-29 19:03:00 26 4
gpt4 key购买 nike

我在将 SharedArrayBuffer 同步到主线程时遇到问题。

场景如下:

我有两个工作人员负责处理我程序的不同方面。第一个 worker 负责对象交互,第二个 worker 负责计算可见性等,主线程将进行可视化。

首先,第一个 Worker 创建一个具有以下布局的 SharedArrayBuffer:

new SharedArrayBuffer(112);
[
Lock: 4 Byte
MetaInfo: 4 Byte
Location: 12 Byte
Scale: 12 Byte
Rotation: 16 Byte
Matrix: 64 Byte
]

然后他将SAB发送给主线程和第二个Worker,并将位置缩放和旋转属性存储在Buffer中。每次更新字段时,他都会锁定 SAB,更新值并将 MetaInfo 字段(转换标志)的第一位设置为真。

如果设置了转换标志,第二个 Worker 将根据给定的位置比例和旋转字段计算矩阵,并将其保存在 Matrix 字段中。之后元信息字段的第二位(矩阵标志)将被设置为真。

如果设置了矩阵标志,主线程现在需要读取最终矩阵。

问题来了:在 worker 上,可以使用 Lock 字段上的 Atomics.wait 方法锁定缓冲区。但是主线程缺少这样的功能,导致卡顿和“跳跃”。是否有一致的方法来防止其他工作人员在读取过程中写入 SAB?

这是我的 SharedArrayBuffer 包装器的代码:

class SharedObject {
SharedBuffer: SharedArrayBuffer; // the shared array buffer
Lock: Int32Array; // view for lockíng the buffer
MetaInfo: Int32Array; // view for meta info
Location: Float32Array;

constructor(buffer) {
// if valid buffer is passed assign it to this object
if (buffer !== undefined && buffer instanceof SharedArrayBuffer && buffer.byteLength == 112) {
this.SharedBuffer = buffer;
} else {
// create new shared array buffer
this.SharedBuffer = new SharedArrayBuffer(112);
}

this.Lock = new Int32Array(this.SharedBuffer, 0, 4);
this.MetaInfo = new Int32Array(this.SharedBuffer, 4, 8);

[ ... init the rest of the views ... ]

// init the lock element
if (buffer === undefined) {
Atomics.store(this.Lock, 0, 1);
}

}

lock() {
Atomics.wait(this.Lock, 0, 0);
Atomics.store(this.Lock, 0, 0);
return true;
}

free() {
if (Atomics.wake(this.Lock, 0, 1) == 0) {
Atomics.store(this.Lock, 0, 1);
}
return true;
}

setFlag(flag) {
this.MetaInfo[0] = this.MetaInfo[0] | flag;
}
isFlagSet(flag) {
return (this.MetaInfo[0] & flag) > 0;
}
resetFlag(flag) {
this.MetaInfo[0] = this.MetaInfo[0] - (this.MetaInfo[0] & flag);
}
}

注意 lock 和 free 方法不能在主线程中使用,因为:

Note: This operation only works with a shared Int32Array and is not allowed on the main thread.

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Atomics/wait

这种设置甚至可以在一个 SharedArrayBuffer 中包含多个独立字段,还是我应该考虑为每个应用程序使用多个 SharedArrayBuffer

最佳答案

经过一些研究,似乎选择了阻止主线程使用 Atomics.wait()。是为了避免同步线程阻塞,因为主线程处理用户事件和页面渲染以及其他服务,允许 Atomics.wait() 会导致 Web 应用程序的用户体验不佳。

SharedArrayBuffer API紧随其后的是 OffscreenCanvas API ,目前在 Chrome 上仍未实现,但在 Firefox 上可用。

使用屏幕外 Canvas ,您可以从用于渲染的 Web Worker 中 Atomics.wait(),在从共享数组读取数据后应用您的 gl 操作缓冲区,然后调用 gl.commit() ,这会将 gl 框架渲染到主线程。

不幸的是,由于 Firefox 是目前唯一支持 OffscreenCanvas API 的浏览器,而 NW.js 仅适用于 Chromium,由于缺乏对Atomics.wait() 和 WebGL 在 Chrome 上的同一个线程中。

关于Javascript将SharedArrayBuffer同步到主线程,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45439334/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com