restringir

De la Viquipèdia, l'enciclopèdia lliure.
Saltar a la navegació Saltar a la cerca

La paraula clau restrict s'utilitza en l'idioma C (començant per l'estàndard C99) per qualificar un punter com a no subjecte a l' aliasing per altres punteres que no se'n declaren. En declarar un punter de restrict , el programador fa una declaració d'intenció, informant al compilador que, en tot el seu cicle de vida, només s'utilitzarà aquell punter i possiblement altres indicadors derivats per accedir a l'objecte apuntat. Si el programador infringeix la declaració d'intenció i s'utilitza un altre punter per accedir a l'objecte, el comportament del programa no està definit .

Aquesta informació permet al compilador generar un codi millor optimitzat: en principi, afegir restrict a l’estàndard C fa que sigui possible salvar la bretxa amb Fortran en aplicacions de computació numèrica . [1]

L'estàndard de llenguatge C ++ no inclou la paraula clau restrict , però molts compiladors implementen una paraula clau no estàndard que proporciona un efecte similar al seu homòleg C, com ara __restrict__ a GCC [2] o __restrict i __declspec(restrict) a Visual C ++ . [3]

Optimització

Si el compilador té la certesa que només un punter pot accedir a un bloc de memòria, és possible generar un codi millor optimitzat, per exemple, canviant l’ordre de les instruccions per realitzar totes les store load o store consecutiva o evitant carregar-ne un mateix. valor (sabent que no es pot canviar mitjançant un altre punter de restrict ). Per exemple, donada la funció

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

els punteres ptrA , ptrB i val podrien accedir a la mateixa regió de memòria ( aliasing de punter ), de manera que el compilador ha de tenir en compte aquesta possibilitat a l’hora de generar el codi de la màquina. Per exemple, gcc -O3 -S (mitjançant la versió 8.2 de gcc ) genera el següent conjunt x86-64 per al cos de la funció

 movq ( % rdx ), % rax
addq % rax , ( % rdi )
movq ( % rdx ), % rax
addq % rax , ( % rsi )
ret

Si s'exclou l'aliasing, calificar els indicadors com a restrict a la declaració

 void updatePtrs ( size_t * restringir ptrA , size_t * restringir ptrB , size_t * restringir val );

el compilador pot assumir legítimament que ptrA , ptrB i val sempre accediran a regions de memòria no superposades i que les operacions realitzades a través d’un punter no tindran cap efecte en els objectes a què fan referència altres punteres (no obstant això, és responsabilitat del programador garantir aquest fet escrivint el codi). Això fa que sigui innecessari val a llegir el valor assenyalat per val després d'executar la primera sentència, i l'assemblea esdevé

 movq ( % rdx ), % rax
addq % rax , ( % rdi )
addq % rax , ( % rsi )
ret

Nota

  1. ^ Ulrich Drepper , Memòria part 5: què poden fer els programadors , a Què han de saber tots els programadors sobre la memòria , lwn.net , 23 d'octubre de 2007.
    «" ... Les regles d'aliasing per defecte dels llenguatges C i C ++ no ajuden el compilador a prendre aquestes decisions (tret que s'utilitzi la restricció, tots els accessos de punter són fonts potencials d'aliasing). Per això, Fortran segueix sent un llenguatge preferit per a la programació numèrica: facilita l’escriptura de codi ràpid. (En teoria, la paraula clau restrict introduïda al llenguatge C a la revisió de 1999 hauria de solucionar el problema. Els compiladors encara no s’han posat al dia. La raó és principalment que és massa incorrecte existeix un codi que enganyaria el compilador i provocaria que generés un codi objecte incorrecte.) "» .
  2. ^ Utilitzant la col·lecció GNU Compiler: Restricted Pointers , a gcc.gnu.org .
  3. ^ __restrict , a msdn.microsoft.com .

Bibliografia

Enllaços externs

Informàtica Portal de TI : accediu a les entrades de Viquipèdia relacionades amb TI