本文摘自:
restrict
是c99引入的新關鍵字,它用於
宣告只會通過該指針對其指向的記憶體空間進行讀寫操作,以便編譯器能進行更好的優化。
我們來看乙個跟memcpy/memmove類似的問題。下面的函式將兩個陣列中對應的元素相加,結果儲存在第三個陣列中。
void
vector_add
(const
double*x
,const
double*y
,double
*result
)
如果這個函式要在多處理器的計算機上執行,編譯器可以做這樣的優化:把這乙個迴圈拆成兩個迴圈,乙個處理器計算i值從0到31的循 環,另乙個處理器計算i值從32到63的迴圈,這樣兩個處理器可以同時工作,使計算時間縮短一半。但是這樣的編譯優化能保證得出正確結果嗎?假如result和x所指的記憶體區間是重疊的,result[0]其實是x[1],result[i]其實是x[i+1],這兩個處理器就不能各幹各的事情了,因為第二個處理器的工作依賴於第乙個處理器的最終計算結果,這種情況下編譯優化的結果是錯的。這樣看來編譯器是不敢隨便做優化了,那麼多處理器提供的並行性就無法利用,豈不可惜?為此,c99引入restrict關鍵字,如果程式設計師把上面的函式宣告為
void vector_add(const double *restrict x, const double *restrict y, double *restrict result)
,就是告訴編譯器可以放心地對這個函式做優化,程式設計師自己會保證這些指標所指的記憶體區間互不重疊。
由於restrict
是c99引入的新關鍵字,目前linux的man page還沒有更新,所以都沒有
restrict
關鍵字,本書的函式原型都取自man page,所以也都沒有restrict關鍵字。但在c99標準中庫函式的原型都在必要的地方加了restrict關鍵字,在
c99中memcpy的原型是
void *
memcpy
(void * restrict s1, const void * restrict s2, size_t n);
,就是告訴呼叫者,這個函式的實現可能會做些優化,編譯器也可能會做些優化,傳進來的指標不允許指向重疊的記憶體區間,否則結果可能是錯的,而memmove的原型是
void *
memmove
(void *s1, const void *s2, size_t n);
,沒有restrict關鍵字,說明傳給這個函式的指標允許指向重疊的記憶體區間。在restrict關鍵字出現之前都是用自然語言描述哪些函式的引數不允許指向重疊的記憶體區間,例如在c89標準的庫函式一章開頭提到,本章描述的所有函式,除非特別說明,都不應該接收兩個指標引數指向重疊的記憶體區間,例如呼叫sprintf時傳進來的格式化字串和結果字串的首位址相同,諸如此類的呼叫都是非法的。本書也遵循這一慣例,除非像memmove這樣特別說明之外,都表示「不允許」。
關於restrict關鍵字更詳細的解釋可以參考[
beganfortran]。
restrict關鍵字用法
概括的說,關鍵字restrict只用於限定指標 該關鍵字用於告知編譯器,所有修改該指標所指向內容的操作全部都是基於 base on 該指標的,即不存在其它進行修改操作的途徑 這樣的後果是幫助編譯器進行更好的 優化,生成更有效率的彙編 舉個簡單的例子 int foo int x,int y 很顯然函式...
restrict關鍵字用法
c99中新增加了乙個型別定義,就是restrict。看了下網上的相關貼子,但還是問題解決的不夠。下面是相關乙個文章,我將在後面再加相關說明 那麼restrict的意義是什麼呢?概括的說,關鍵字restrict只用於限定指標 該關鍵字用於告知編譯器,所有修改該指標所指向內容的操作全部都是基於 base...
restrict關鍵字用法
2016年10月11日 16 59 12 the hungry brain 閱讀數 1626 標籤 c語言更多 個人分類 讀書筆記 c99中新增加了乙個型別定義,就是restrict。概括的說,關鍵字restrict只用於限定指標 該關鍵字用於告知編譯器,所有修改該指標所指向內容的操作全部都是基於 ...