
在 C 語言中,於 C99 標準(1999 年)引入了 restrict
關鍵字,主要用於最佳化指針(pointer)的操作。它允許程式開發人員向編譯器提供額外的資訊,用以標識某個指針是程式中用於訪問特定資料物件的唯一方式。
當一個指針(pointer)被宣告為 restrict
時,也意味著告訴編譯器可以假設透過該指針所訪問的記憶體不會與其他指針所訪問的記憶體重疊。在這樣的前提或承諾下,編譯器得以進行更加激進的最佳化,因為此時不必擔心不同指針會指向相同的記憶體位址。
換句話說:關鍵字 restrict
用於告訴編譯器,某個指針所指向的記憶體區域,在程式中只會使用該指針來訪問與操作,亦即其他指針都不會指向該一個記憶體位置。
// 沒有 restrict 的情況
void example(int* a, int* b, size_t n) {
for (size_t i = 0; i < n; ++i) {
a[i] += b[i];
}
}
// 使用 restrict 的情況
void example(int* restrict a, int* restrict b, size_t n) {
for (size_t i = 0; i < n; ++i) {
a[i] += b[i];
}
}
- 沒有
restrict
的情況:如果指針a
與b
指向同一塊記憶體位址,編譯器需要保證所有的記憶體讀寫順序正確,因此最佳化受到限制。 - 使用
restrict
的情況:由於程式開發者保證了指針 a 與 b 會指向不同的記憶體區域,因此編譯器可以重新排列加載指令(load instruction)和存儲指令(store instruction),或者使用 SIMD 指令(Single Instruction, Multiple Data)來最佳化程式碼。
使用
restrict
需要編譯器配合,有些編譯器可能會在預設最佳化級別較低的情况下忽略 restrict
關鍵字的作用。
切記
restrict
關鍵字只能用於指針(point)型別,不能用於非指針型別的變數。除此之外,開發人員需要保證使用 restrict
指針訪問的記憶體區域,不會與其他指針訪問的記憶體區域,如果違反這個條件,則程式會有不可預期的行為。
張貼留言