奶头挺立呻吟高潮av全片,成人试看120秒体验区,性欧美极品v,A片高潮抽搐揉捏奶头视频

C語(yǔ)言

C語(yǔ)言關(guān)鍵字RESTRICT介紹

時(shí)間:2025-01-20 19:17:33 美云 C語(yǔ)言 我要投稿
  • 相關(guān)推薦

C語(yǔ)言關(guān)鍵字RESTRICT介紹

  學(xué)習(xí)C語(yǔ)言也有好長(zhǎng)時(shí)間了,相信大家在學(xué)習(xí)C語(yǔ)言的過(guò)程中也都有所收獲,不過(guò),也應(yīng)該遇到了許多問(wèn)題。今天小編在這里就幫同學(xué)們介紹一下怎么了解restrict這個(gè)詞。

  C語(yǔ)言關(guān)鍵字RESTRICT介紹

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

  Pointer aliasing 是指兩個(gè)或以上的指針指向同一數(shù)據(jù),例如

  int i = 0;

  int *a = &i;

  int *b = &i;

  這樣會(huì)有什么問(wèn)題呢?

  如果編譯器采用最安全的假設(shè),即不理會(huì)兩個(gè)指針會(huì)否指向同一數(shù)據(jù),那么通過(guò)指針讀寫(xiě)數(shù)據(jù)是很直觀的。

  然而,這種假設(shè)會(huì)令編譯器無(wú)法優(yōu)化,例如:

  int foo(int *a, int *b)

  {

  *a = 5;

  *b = 6;

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

  }

  如果 a 和 b 都指向同一數(shù)據(jù),*b = 6 會(huì)導(dǎo)致 *a = 6,返回12。所以編譯器在做 *a + *b 的時(shí)候,需要重新讀取 *a 指向的數(shù)據(jù):

  foo:

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

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

  movl (%rdi), %eax # 重新讀取 *a (因?yàn)橛锌赡鼙簧弦恍兄噶钤斐筛淖?

  addl $6, %eax # 加上 6

  ret

  如果我們確保兩個(gè)指針不指向同一數(shù)據(jù),就可以用 restrict 修飾指針類(lèi)型:

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

  {

  *a = 5;

  *b = 6;

  return *a + *b;

  }

  編譯器就可以根據(jù)這個(gè)信息,做出優(yōu)化:

  rfoo:

  movl $11, %eax # 在編譯期已計(jì)算出 11

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

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

  ret

  但如果用了 restrict 去修飾兩個(gè)指針,而它們?cè)谧饔糜騼?nèi)又指向同一地址,那么是未定義行為。

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

  以個(gè)人經(jīng)驗(yàn)而言,編寫(xiě)代碼時(shí)通常會(huì)忽略 pointer aliasing 的問(wèn)題。更常見(jiàn)是在性能剖測(cè)時(shí),通過(guò)反編譯看到很多冗余的讀取指令,才會(huì)想到加入 restrict 關(guān)鍵字來(lái)提升性能。

  RESTRICT簡(jiǎn)介

  restrict是c99標(biāo)準(zhǔn)引入的,它只可以用于限定和約束指針,并表明指針是訪問(wèn)一個(gè)數(shù)據(jù)對(duì)象的唯一且初始的方式。即它告訴編譯器,所有修改該指針?biāo)赶騼?nèi)存中內(nèi)容的操作都必須通過(guò)該指針來(lái)修改,而不能通過(guò)其它途徑(其它變量或指針)來(lái)修改;這樣做的好處是,能幫助編譯器進(jìn)行更好的優(yōu)化代碼,生成更有效率的匯編代碼。如 int *restrict ptr, ptr 指向的內(nèi)存單元只能被 ptr 訪問(wèn)到,任何同樣指向這個(gè)內(nèi)存單元的其他指針都是未定義的,直白點(diǎn)就是無(wú)效指針。restrict 的出現(xiàn)是因?yàn)?C 語(yǔ)言本身固有的缺陷,C 程序員應(yīng)當(dāng)主動(dòng)地規(guī)避這個(gè)缺陷,而編譯器也會(huì)很配合地優(yōu)化你的代碼。

  RESTRICT應(yīng)用

  C庫(kù)中有兩個(gè)函數(shù)可以從一個(gè)位置把字節(jié)復(fù)制到另一個(gè)位置。在C99標(biāo)準(zhǔn)下,它們的原型如下:

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

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

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

  關(guān)鍵字restrict有兩個(gè)讀者。一個(gè)是編譯器,它告訴編譯器可以自由地做一些有關(guān)優(yōu)化的假定。另一個(gè)讀者是用戶(hù),他告訴用戶(hù)僅使用滿(mǎn)足restrict要求的參數(shù)。一般,編譯器無(wú)法檢查您是否遵循了這一限制,如果您蔑視它也就是在讓自己冒險(xiǎn)。

【C語(yǔ)言關(guān)鍵字RESTRICT介紹】相關(guān)文章:

C語(yǔ)言關(guān)鍵字05-09

C語(yǔ)言關(guān)鍵字及其解釋06-01

C語(yǔ)言關(guān)鍵字有哪些02-28

c語(yǔ)言的關(guān)鍵字有哪些06-15

C語(yǔ)言關(guān)鍵字const用法03-16

C語(yǔ)言的關(guān)鍵字define的使用08-03

C語(yǔ)言關(guān)鍵字const的使用05-23

C語(yǔ)言的關(guān)鍵字enum的使用04-28

C語(yǔ)言的關(guān)鍵字知識(shí)要點(diǎn)04-21

主站蜘蛛池模板: 凤冈县| 游戏| 文安县| 宜宾县| 遂昌县| 南投县| 西峡县| 错那县| 霍林郭勒市| 乌拉特后旗| 金阳县| 留坝县| 垣曲县| 铜陵市| 仙桃市| 大新县| 金阳县| 大渡口区| 堆龙德庆县| 绥中县| 温州市| 长垣县| 安阳县| 尚志市| 永吉县| 高碑店市| 中西区| 绿春县| 韶关市| 聊城市| 延寿县| 雷山县| 通许县| 朝阳县| 勐海县| 建湖县| 循化| 富川| 绿春县| 大连市| 榆中县|