Atomics.pause()
Atomics.pause() 靜態方法提供了一種微等待原語,它提示 CPU 呼叫者正在忙等待(spinning)以訪問共享資源。這允許系統減少分配給核心(如功耗)或執行緒的資源,而無需讓出當前執行緒。
除了計時外,pause() 沒有其他可觀察的行為。具體行為取決於 CPU 架構和作業系統。例如,在 Intel x86 上,它可能是一個 pause 指令,根據 Intel 的最佳化手冊。在某些平臺上,它可能是一個空操作(no-op)。
語法
Atomics.pause()
Atomics.pause(durationHint)
引數
durationHint可選-
一個實現可以用來確定等待時間的整數。對於值
n + 1,實現等待的時間至少與給定值n的時間一樣長。具體數字沒有實際意義。在納秒到幾十納秒的量級上,可能存在內部最大暫停時間的上限。這可以用來透過增加傳遞的durationHint來實現 退避策略。不能保證實現一定會利用此提示。
返回值
無(undefined)。
異常
TypeError-
如果
durationHint不是整數或undefined,則丟擲錯誤。
示例
使用 Atomics.pause()
呼叫 Atomics.wait() 或 Atomics.waitAsync() 來等待訪問共享記憶體會導致執行緒被排程出核心,並在等待結束後重新排程回核心。在高爭用時期,這非常高效,因為訪問共享記憶體可能需要一些時間。當爭用較低時,通常更有效的方法是在不讓出執行緒的情況下輪詢鎖:這種方法稱為 忙等待 或 自旋鎖。pause() 方法透過向 CPU 提供執行緒正在做什麼的提示,從而降低其對資源的需求,使您能夠更有效地自旋鎖等待。
為了兼顧這兩種情況,一種常見的方法是首先嚐試自旋鎖,希望能快速獲取鎖(爭用低),然後在一段時間後如果仍未獲得鎖,則進行等待。如果我們已經透過自旋鎖獲取了鎖,那麼 wait() 呼叫將是一個空操作。
下面的示例顯示瞭如何將這種方法與 Atomics.pause() 和 Atomics.wait() 結合使用。
警告:不建議在主執行緒上使用自旋鎖,因為它會凍結整個頁面。總的來說,除非經過非常仔細的設計,否則自旋鎖的效能可能並不比常規等待更好。
// Imagine another thread also has access to this shared memory
const sab = new SharedArrayBuffer(1024);
const i32 = new Int32Array(sab);
// Fast path: spin the CPU for a short while
let spin = 0;
do {
if (Atomics.compareExchange(i32, 0, 0, 1) === 0) {
break;
}
Atomics.pause();
spin++;
} while (spin < 10);
// Slow path: wait for the lock
// This can only be called in a worker thread,
// because the main thread cannot be blocked
Atomics.wait(i32, 0, 1);
退避策略
durationHint 引數可用於實現退避策略。例如,執行緒可以從一個小的提示開始,並在每次迭代中指數級增加提示。這比多次呼叫 pause() 要好,因為在未 JIT 編譯的程式碼中,函式呼叫本身就有很高的開銷。
注意:實現可能根本不使用 durationHint,而是始終等待一個固定的時間。
// Exponential backoff
for (let hint = 1; hint < 1000; hint *= 2) {
Atomics.pause(hint);
}
// Linear backoff
for (let hint = 1; hint < 100; hint++) {
Atomics.pause(hint);
}
規範
| 規範 |
|---|
| Atomics.pause # Atomics.pause |
瀏覽器相容性
載入中…