restrânge

De la Wikipedia, enciclopedia liberă.
Salt la navigare Salt la căutare

Cuvânt cheie restrict este utilizat în limbajul C (începând cu standardul C99) pentru a se califica un indicator ca să nu fac obiectul aliasing de alte indicii care nu sunt declarate de la ea. În declararea unui indicator de restrict , programatorul face o declarație de intenție, informând compilatorul că, în întregul său ciclu de viață, doar acel indicator și eventual alți indicatori derivați din acesta vor fi folosiți pentru a accesa obiectul ascuțit. Dacă declarația de intenție este încălcată de programator și un alt indicator este utilizat pentru a accesa obiectul, comportamentul programului este nedefinit .

Aceste informații permit compilatorului să genereze un cod mai bine optimizat: în principiu, adăugarea de restrict la standardul C face posibilă reducerea decalajului cu Fortran în aplicațiile de calcul numeric . [1]

Standardul de limbaj C ++ nu include cuvântul cheie restrict , dar mulți compilatori implementează un cuvânt cheie nestandard care oferă un efect similar omologului său C, cum ar fi __restrict__ în GCC [2] sau __restrict și __declspec(restrict) în Visual C ++ . [3]

Optimizare

Dacă compilatorul este sigur că doar un pointer poate accesa un bloc de memorie, este posibil să se genereze un cod mai bine optimizat, de exemplu prin schimbarea ordinii instrucțiunilor pentru a efectua toate operațiile de load sau store consecutiv sau evitând încărcarea unuia valoare (știind că nu poate fi modificată printr-un alt indicator de restrict ). De exemplu, având în vedere funcția

 void updatePtrs (size_t * PTRA, size_t * ptrB, size_t * val)
{
  * ptrA + = * val ;
  * ptrB + = * val ;
}

indicatorii ptrA , ptrB și val ar putea accesa aceeași regiune de memorie ( aliasing pointer ), astfel încât compilatorul trebuie să ia în considerare această posibilitate atunci când generează codul mașinii. De exemplu, gcc -O3 -S (folosind versiunea gcc 8.2) generează următorul ansamblu x86-64 pentru corpul funcției

 movq (% RDX),% rax
addq% rax, (% DZR)
movq (% RDX),% rax
addq% rax, (% rsi)
ret

Dacă aliasarea este exclusă, calificarea indicatoarelor ca restrict în declarație

 updatePtrs nule (size_t * restricționa PTRA, size_t * restricționa ptrB, size_t * restricționați val);

compilatorul poate presupune în mod legitim că ptrA , ptrB și val vor accesa întotdeauna regiuni de memorie care nu se suprapun și operațiunile efectuate printr-un pointer nu vor avea niciun efect asupra obiectelor la care se referă alți indicatori (este totuși responsabilitatea programatorului să garanteze acest fapt în scris cod). Acest lucru face inutilă citirea din nou a valorii indicate de val după executarea primei instrucțiuni, iar ansamblul devine

 movq (% RDX),% rax
addq% rax, (% DZR)
addq% rax, (% rsi)
ret

Notă

  1. ^ Ulrich Drepper , Memoria partea 5: Ce pot face programatorii , în Ce ar trebui să știe fiecare programator despre memorie , lwn.net , 23 octombrie 2007.
    «" ... Regulile implicite de aliasing ale limbajelor C și C ++ nu ajută compilatorul să ia aceste decizii (dacă nu se folosește restricție, toate accesele pointerului sunt surse potențiale de aliasing). Acesta este motivul pentru care Fortran este încă un limbaj preferat pentru programarea numerică: facilitează scrierea unui cod rapid. (În teorie, cuvântul cheie restricționat introdus în limbajul C în revizuirea din 1999 ar trebui să rezolve problema. Compilatoarele nu au ajuns încă din urmă. Motivul este în principal faptul că prea mult este incorect există un cod care ar induce în eroare compilatorul și ar determina generarea unui cod obiect incorect.) "» .
  2. ^ Folosind colecția GNU Compiler: Restricted Pointers , la gcc.gnu.org .
  3. ^ __restrict , pe msdn.microsoft.com .

Bibliografie

linkuri externe

Informatică Portal IT : accesați intrările Wikipedia care se ocupă cu IT