<pre id="bbfd9"><del id="bbfd9"><dfn id="bbfd9"></dfn></del></pre>

          <ruby id="bbfd9"></ruby><p id="bbfd9"><mark id="bbfd9"></mark></p>

          <p id="bbfd9"></p>

          <p id="bbfd9"><cite id="bbfd9"></cite></p>

            <th id="bbfd9"><form id="bbfd9"><dl id="bbfd9"></dl></form></th>

            <p id="bbfd9"><cite id="bbfd9"></cite></p><p id="bbfd9"></p>
            <p id="bbfd9"><cite id="bbfd9"><progress id="bbfd9"></progress></cite></p>
            C語言

            C語言關鍵字RESTRICT介紹

            時間:2025-01-20 19:17:33 美云 C語言 我要投稿
            • 相關推薦

            C語言關鍵字RESTRICT介紹

              學習C語言也有好長時間了,相信大家在學習C語言的過程中也都有所收獲,不過,也應該遇到了許多問題。今天小編在這里就幫同學們介紹一下怎么了解restrict這個詞。

              C語言關鍵字RESTRICT介紹

              要理解 restrict,先要知道什么是 Pointer aliasing。

              Pointer aliasing 是指兩個或以上的指針指向同一數據,例如

              int i = 0;

              int *a = &i;

              int *b = &i;

              這樣會有什么問題呢?

              如果編譯器采用最安全的假設,即不理會兩個指針會否指向同一數據,那么通過指針讀寫數據是很直觀的。

              然而,這種假設會令編譯器無法優化,例如:

              int foo(int *a, int *b)

              {

              *a = 5;

              *b = 6;

              return *a + *b; // 不一定是 11!

              }

              如果 a 和 b 都指向同一數據,*b = 6 會導致 *a = 6,返回12。所以編譯器在做 *a + *b 的時候,需要重新讀取 *a 指向的數據:

              foo:

              movl $5, (%rdi) # 存儲 5 至 *a

              movl $6, (%rsi) # 存儲 6 至 *b

              movl (%rdi), %eax # 重新讀取 *a (因為有可能被上一行指令造成改變)

              addl $6, %eax # 加上 6

              ret

              如果我們確保兩個指針不指向同一數據,就可以用 restrict 修飾指針類型:

              int rfoo(int *restrict a, int *restrict b)

              {

              *a = 5;

              *b = 6;

              return *a + *b;

              }

              編譯器就可以根據這個信息,做出優化:

              rfoo:

              movl $11, %eax # 在編譯期已計算出 11

              movl $5, (%rdi) # 存儲 5 至 *a

              movl $6, (%rsi) # 存儲 6 至 *b

              ret

              但如果用了 restrict 去修飾兩個指針,而它們在作用域內又指向同一地址,那么是未定義行為。

              總括而言,restrict 是為了告訴編譯器額外信息(兩個指針不指向同一數據),從而生成更優化的機器碼。注意,編譯器是無法自行在編譯期檢測兩個指針是否 alias。如使用 restrict,程序員也要遵守契約才能得出正確的代碼(指針不能指向相同數據)。

              以個人經驗而言,編寫代碼時通常會忽略 pointer aliasing 的問題。更常見是在性能剖測時,通過反編譯看到很多冗余的讀取指令,才會想到加入 restrict 關鍵字來提升性能。

              RESTRICT簡介

              restrict是c99標準引入的,它只可以用于限定和約束指針,并表明指針是訪問一個數據對象的唯一且初始的方式。即它告訴編譯器,所有修改該指針所指向內存中內容的操作都必須通過該指針來修改,而不能通過其它途徑(其它變量或指針)來修改;這樣做的好處是,能幫助編譯器進行更好的優化代碼,生成更有效率的匯編代碼。如 int *restrict ptr, ptr 指向的內存單元只能被 ptr 訪問到,任何同樣指向這個內存單元的其他指針都是未定義的,直白點就是無效指針。restrict 的出現是因為 C 語言本身固有的缺陷,C 程序員應當主動地規避這個缺陷,而編譯器也會很配合地優化你的代碼。

              RESTRICT應用

              C庫中有兩個函數可以從一個位置把字節復制到另一個位置。在C99標準下,它們的原型如下:

              void * memcpy(void * restrict s1, const void * restrict s2,size_tn);

              void * memmove(void * s1, const void * s2,size_tn);

              這兩個函數均從s2指向的位置復制n字節數據到s1指向的位置,且均返回s1的值。兩者之間的差別由關鍵字restrict造成,即memcpy()可以假定兩個內存區域沒有重疊。memmove()函數則不做這個假定,因此,復制過程類似于首先將所有字節復制到一個臨時緩沖區,然后再復制到最終目的地。如果兩個區域存在重疊時使用memcpy()會怎樣?其行為是不可預知的,既可以正常工作,也可能失敗。在不應該使用memcpy()時,編譯器不會禁止使用memcpy()。因此,使用memcpy()時,您必須確保沒有重疊區域。這是程序員的任務的一部分。

              關鍵字restrict有兩個讀者。一個是編譯器,它告訴編譯器可以自由地做一些有關優化的假定。另一個讀者是用戶,他告訴用戶僅使用滿足restrict要求的參數。一般,編譯器無法檢查您是否遵循了這一限制,如果您蔑視它也就是在讓自己冒險。

            【C語言關鍵字RESTRICT介紹】相關文章:

            C語言關鍵字05-09

            C語言關鍵字及其解釋06-01

            C語言關鍵字有哪些02-28

            c語言的關鍵字有哪些06-15

            C語言關鍵字const用法03-16

            C語言的關鍵字define的使用08-03

            C語言關鍵字const的使用05-23

            C語言的關鍵字enum的使用04-28

            C語言的關鍵字知識要點04-21

                    <pre id="bbfd9"><del id="bbfd9"><dfn id="bbfd9"></dfn></del></pre>

                    <ruby id="bbfd9"></ruby><p id="bbfd9"><mark id="bbfd9"></mark></p>

                    <p id="bbfd9"></p>

                    <p id="bbfd9"><cite id="bbfd9"></cite></p>

                      <th id="bbfd9"><form id="bbfd9"><dl id="bbfd9"></dl></form></th>

                      <p id="bbfd9"><cite id="bbfd9"></cite></p><p id="bbfd9"></p>
                      <p id="bbfd9"><cite id="bbfd9"><progress id="bbfd9"></progress></cite></p>
                      飘沙影院