1. 程式人生 > 其它 >golang sync.once done 熱路徑

golang sync.once done 熱路徑

sync.once 為什麼會將done放在結構體第一個欄位,就能夠提升效能了?
我們先來看看sync.once的結構體:

// Once is an object that will perform exactly one action.
//
// A Once must not be copied after first use.
type Once struct {
 // done indicates whether the action has been performed.
 // It is first in the struct because it is used in the hot path.
 // The hot path is inlined at every call site.
 // Placing done first allows more compact instructions on some architectures (amd64/386),
 // and fewer instructions (to calculate offset) on other architectures.
 done uint32
 m    Mutex
}

從欄位 done 前有一段註釋,說明了done 為什麼是第一個欄位。

done 在熱路徑中,done 放在第一個欄位,能夠減少 CPU 指令,也就是說,這樣做能夠提升效能。

熱路徑(hot path)是程式非常頻繁執行的一系列指令,sync.Once 絕大部分場景都會訪問 o.done,在熱路徑上是比較好理解的。如果 hot path 編譯後的機器碼指令更少,更直接,必然是能夠提升效能的。

為什麼放在第一個欄位就能夠減少指令呢?因為結構體第一個欄位的地址和結構體的指標是相同的,如果是第一個欄位,直接對結構體的指標解引用即可。如果是其他的欄位,除了結構體指標外,還需要計算與第一個值的偏移(calculate offset)。在機器碼中,偏移量是隨指令傳遞的附加值,CPU 需要做一次偏移值與指標的加法運算,才能獲取要訪問的值的地址。因為,訪問第一個欄位的機器程式碼更緊湊,速度更快。

參考:https://mp.weixin.qq.com/s/Lv2XTD-SPnxT2vnPNeREbg