effacer un petit tableau d’entiers: memset vs. for loop

Il existe deux manières de mettre à zéro un tableau entier / flottant:

memset(array, 0, sizeof(int)*arraysize); 

ou:

 for (int i=0; i <arraysize; ++i) array[i]=0; 

de toute évidence, memset est plus rapide pour les grandes arraysize . Cependant, à quel point la surcharge de memset est-elle réellement supérieure à la surcharge de la boucle for? Par exemple, pour un tableau de taille 5 – quel serait le meilleur? La première, la deuxième version, voire la version non roulée:

 array[0] = 0; array[1] = 0; array[2] = 0; array[3] = 0; array[4] = 0; 

Selon toute probabilité, memset () sera intégré par votre compilateur (la plupart des compilateurs le traitent comme un «insortingnsèque», ce qui signifie qu’il est intégré, sauf peut-être aux optimisations les plus faibles ou à moins qu’il ne soit explicitement désactivé).

Par exemple, voici quelques notes de version de GCC 4.3 :

La génération de code de déplacement de bloc ( memcpy ) et de bloc ( memset ) a été réécrite. GCC peut maintenant choisir le meilleur algorithme (boucle, boucle déroulée, instruction avec préfixe rep ou appel de bibliothèque) en fonction de la taille du bloc en cours de copie et du processeur optimisé. Une nouvelle option -minline-ssortingngops-dynamically a été ajoutée. Avec cette option, les opérations de chaîne de taille inconnue sont étendues de telle sorte que les petits blocs sont copiés par du code en ligne, tandis que pour les grands blocs, un appel de bibliothèque est utilisé. Cela se traduit par un code plus rapide que -minline-all-ssortingngops lorsque l’implémentation de la bibliothèque est capable d’utiliser des indicateurs de hiérarchie de cache. L’heuristique qui choisit l’algorithme particulier peut être écrasée via la -mssortingngop-strategy . Récemment, memset de valeurs différentes de 0 est inséré.

Il est possible que le compilateur fasse quelque chose de similaire avec les exemples alternatifs que vous avez donnés, mais je parierais que c’est moins probable.

Et il est plus facile à comprendre et plus évident en un coup d’œil quelle est l’intention de démarrer (pas que la boucle soit particulièrement difficile à comprendre).

Comme Michael l’a déjà noté, gcc et moi-même pensons que la plupart des autres compilateurs optimisent déjà ce problème. Par exemple, gcc tourne ceci

 char arr[5]; memset(arr, 0, sizeof arr); 

dans

 movl $0x0,  movb $0x0,  

Ça ne va pas mieux que ça …

Il n’y a aucun moyen de répondre à la question sans mesurer. Cela dépendra entièrement des implémentations du compilateur, du processeur et de la bibliothèque d’exécution.

memset () peut être un peu “odeur de code”, car il peut être enclin à tamponner les débordements, les inversions de parameters et a la capacité regrettable de ne supprimer que les octets. Cependant, il y a fort à parier que ce sera «le plus rapide» sauf dans les cas extrêmes.

J’ai tendance à utiliser une macro pour envelopper ceci pour éviter certains problèmes:

 #define CLEAR(s) memset(&(s), 0, sizeof(s)) 

Cela évite les calculs de taille et élimine le problème de permutation des parameters length et vlaue.

En bref, utilisez memset () “sous le capot”. Ecrivez ce que vous avez l’intention de faire et laissez le compilateur s’inquiéter des optimisations. La plupart sont incroyablement bons.

Considérant que ce code en soi, tout a déjà été dit. Mais si vous le considérez dans son programme, dont je ne sais rien, on peut faire autre chose. Par exemple, si ce code doit être exécuté chaque fois pour effacer un tableau, vous pouvez exécuter un thread qui alloue en permanence un nouveau tableau d’éléments zéro à une variable globale, ce qui nécessite que le tableau soit effacé, pointe simplement sur.

Ceci est une troisième option. Bien sûr, si vous prévoyez d’exécuter votre code sur un processeur avec au moins deux cœurs, cela a du sens. De plus, le code doit être exécuté plus d’une fois pour voir les avantages. Pour une exécution unique, vous pouvez déclarer un tableau rempli de zéros, puis le pointer si nécessaire.

J’espère que cela peut aider quelqu’un