52 votes

Le mot-clé restrict apporte-t-il des avantages significatifs dans gcc / g++ ?

Quelqu'un a-t-il vu des chiffres ou des analyses sur l'utilisation ou non du langage C / C++ ? restrict dans gcc / g++ apporte un gain de performance significatif dans la réalité (et pas seulement en théorie) ?

J'ai lu divers articles recommandant ou dénigrant son utilisation, mais je n'ai pas trouvé de chiffres réels démontrant concrètement les arguments des deux parties.

EDIT

Je sais que restrict ne fait pas officiellement partie de C++, mais il est supporté par certains compilateurs et j'ai lu un article de Christer Ericson qui recommande fortement son utilisation.

52voto

Nils Pipenbrinck Points 41006

Le mot-clé restrict fait une différence.

J'ai vu des améliorations d'un facteur 2 et plus dans certaines situations (traitement d'images). Mais la plupart du temps, la différence n'est pas si importante. Environ 10%.

Voici un petit exemple qui illustre la différence. J'ai écrit une transformation vectorielle * matricielle 4x4 très basique comme test. Notez que je dois forcer la fonction à ne pas être inlined. Sinon, GCC détecte qu'il n'y a pas de pointeurs aliasing dans mon code de référence et que la restriction ne ferait pas de différence à cause de l'inlining.

J'aurais également pu déplacer la fonction de transformation dans un autre fichier.

#include <math.h>

#ifdef USE_RESTRICT
#else
#define __restrict
#endif

void transform (float * __restrict dest, float * __restrict src, 
                float * __restrict matrix, int n) __attribute__ ((noinline));

void transform (float * __restrict dest, float * __restrict src, 
                float * __restrict matrix, int n)
{
  int i;

  // simple transform loop.

  // written with aliasing in mind. dest, src and matrix 
  // are potentially aliasing, so the compiler is forced to reload
  // the values of matrix and src for each iteration.

  for (i=0; i<n; i++)
  {
    dest[0] = src[0] * matrix[0] + src[1] * matrix[1] + 
              src[2] * matrix[2] + src[3] * matrix[3];

    dest[1] = src[0] * matrix[4] + src[1] * matrix[5] + 
              src[2] * matrix[6] + src[3] * matrix[7];

    dest[2] = src[0] * matrix[8] + src[1] * matrix[9] + 
              src[2] * matrix[10] + src[3] * matrix[11];

    dest[3] = src[0] * matrix[12] + src[1] * matrix[13] + 
              src[2] * matrix[14] + src[3] * matrix[15];

    src  += 4;
    dest += 4;
  }
}

float srcdata[4*10000];
float dstdata[4*10000];

int main (int argc, char**args)
{
  int i,j;
  float matrix[16];

  // init all source-data, so we don't get NANs  
  for (i=0; i<16; i++)   matrix[i] = 1;
  for (i=0; i<4*10000; i++) srcdata[i] = i;

  // do a bunch of tests for benchmarking. 
  for (j=0; j<10000; j++)
    transform (dstdata, srcdata, matrix, 10000);
}

Résultats : (sur mon Core Duo 2 Ghz)

nils@doofnase:~$ gcc -O3 test.c
nils@doofnase:~$ time ./a.out

real    0m2.517s
user    0m2.516s
sys     0m0.004s

nils@doofnase:~$ gcc -O3 -DUSE_RESTRICT test.c
nils@doofnase:~$ time ./a.out

real    0m2.034s
user    0m2.028s
sys     0m0.000s

Au-delà du pouce, une exécution 20% plus rapide, sur que système.

Pour montrer à quel point cela dépend de l'architecture, j'ai laissé le même code s'exécuter sur un CPU embarqué Cortex-A8 (en ajustant un peu le nombre de boucles car je ne veux pas attendre aussi longtemps) :

root@beagleboard:~# gcc -O3 -mcpu=cortex-a8 -mfpu=neon -mfloat-abi=softfp test.c
root@beagleboard:~# time ./a.out

real    0m 7.64s
user    0m 7.62s
sys     0m 0.00s

root@beagleboard:~# gcc -O3 -mcpu=cortex-a8 -mfpu=neon -mfloat-abi=softfp -DUSE_RESTRICT test.c 
root@beagleboard:~# time ./a.out

real    0m 7.00s
user    0m 6.98s
sys     0m 0.00s

Ici, la différence n'est que de 9% (même compilateur d'ailleurs).

6voto

George Points 51

L'article Démystifier le mot-clé de restriction fait référence au document Pourquoi l'aliasing spécifié par le programmeur est une mauvaise idée. (pdf), qui affirme qu'elle n'est généralement d'aucune utilité et fournit des mesures à l'appui.

-1voto

Clifford Points 29933

Notez que les compilateurs C++ qui permettent l'utilisation de l'option restrict Le mot-clé peut encore l'ignorer. C'est le cas par exemple ici .

-2voto

raphaelr Points 36

J'ai testé ce Programme C. Sans restrict il a fallu 12,640 secondes pour terminer, avec restrict 12.516. On dirait qu'il peut sauver un peu de temps.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X