AccueilđŸ‡«đŸ‡·Chercher

restrict

Dans le langage de programmation C, Ă  partir du standard C99, restrict est un mot-clĂ© qui peut ĂȘtre utilisĂ© dans les dĂ©clarations de pointeur. Le mot-clĂ© restrict  est une dĂ©claration d'intention donnĂ©e par le programmeur pour le compilateur. Il indique que pour la durĂ©e de vie du pointeur, seul le pointeur lui-mĂȘme ou une valeur directement issue (comme pointer + 1​) sera utilisĂ© pour accĂ©der Ă  l'objet vers lequel il pointe. Cela limite les effets de l'aliasing de pointeur, aidant aux optimisations. Si la dĂ©claration d'intention n'est pas respectĂ©e et que l'objet est atteint par un pointeur indĂ©pendant, cela se traduira par un comportement indĂ©fini. L'utilisation du mot-clĂ© restrict permet, en principe, d'obtenir la mĂȘme performance que le mĂȘme programme Ă©crit en Fortran[1].

C++ n'a pas de support standard de restrict, mais de nombreux compilateurs ont des Ă©quivalents qui fonctionnent habituellement en C++ et en C, tels que __restrict__ pour GCC et Clang , et __restrict et __declspec(restrict) pour Visual C++.

Optimisation

Si le compilateur sait qu'il y a seulement un pointeur vers un bloc de mémoire, il peut produire un code mieux optimisé.

Par exemple :

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

Dans le code ci-dessus, les pointeurs ptrA, ptrB, et val peuvent se rĂ©fĂ©rer au mĂȘme emplacement mĂ©moire, si bien que le compilateur pourrait gĂ©nĂ©rer un code moins optimal :

load R1 ← *val ; Charge la valeur pointĂ© par val
load R2 ← *ptrA ; Charge la valeur pointĂ© par ptrA
add R2 += R1 ; Effectuer une Addition
set R2 → *ptrA ; mettre Ă  jour la valeur pointĂ© par ptrA
; De mĂȘme pour ptrB, notez que val est chargĂ© Ă  deux reprises, parce que
; ptrA peut ĂȘtre Ă©gal Ă  val (c'est Ă  dire, pointe vers le mĂȘme emplacement).
load R1 ← *val
load R2 ← *ptrB
add R2 += R1
set R2 → *ptrB

Toutefois, si le mot-clĂ© restrict est utilisĂ© et que la fonction ci-dessus est dĂ©clarĂ©e comme :

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

alors le compilateur est autorisĂ© Ă  supposer que ptrA, ptrB et val pointent vers diffĂ©rents emplacements et que la mise Ă  jour d'un pointeur n'affectera pas les autres pointeurs. Le programmeur (non le compilateur) est responsable de veiller Ă  ce que les pointeurs ne pointent pas les mĂȘmes endroits.

Maintenant que le compilateur peut générer un meilleur code comme suit :

load R1 ← *val
load R2 ← *ptrA
add R2 += R1
set R2 → *ptrA
; Notez que val n'est pas rechargé,
; parce que le compilateur sait que c'est inchangé
load R2 ← *ptrB
add R2 += R1
set R2 → *ptrB

Notez que le code assembleur est plus court parce que la valeur pointée par val n'est chargée qu'une seule fois.

On peut remarquer que dans notre cas, ces deux signatures gĂ©nĂšre aussi le mĂȘme code :

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

En effet, il est suffisant de promettre au compilateur que ptrA n'écrira pas dans val , ou que val ne sera pas modifié par ptrA. Ce n'est pas vrai pour ptrB à cause de l'ordre des opérations dans la fonction.

Références

  1. Ulrich Drepper, « Memory part 5: What programmers can do », What every programmer should know about memory, sur What every programmer should know about memory, lwn.net,  : « "...The default aliasing rules of the C and C++ languages do not help the compiler making these decisions (unless restrict is used, all pointer accesses are potential sources of aliasing). This is why Fortran is still a preferred language for numeric programming: it makes writing fast code easier. (In theory the restrict keyword introduced into the C language in the 1999 revision should solve the problem. Compilers have not caught up yet, though. The reason is mainly that too much incorrect code exists which would mislead the compiler and cause it to generate incorrect object code.)" »

Voir aussi

Articles connexes

Liens externes

Cet article est issu de wikipedia. Text licence: CC BY-SA 4.0, Des conditions supplĂ©mentaires peuvent s’appliquer aux fichiers multimĂ©dias.