• # Vectorisation illégale

    Posté par . En réponse au journal Recherche de valeur dans un tableau et l'écosystème des compilateurs C++. Évalué à 8.

    Je n'ai pas regardé dans les compilateurs actuels, mais en règle général, la vectorisation n'est pas possible dans les boucles non-pures, c'est à dire contenant un break ou un return conditionnel. Je ne dis pas que c'est toujours impossible mais c'est rarement intéressant donc les compilateurs n'essayent même pas.

    Je tiens aussi à signaler que strictement parlant, la vectorisation SSE proposée ici est illégale. Le problème est que les données sont lues par blocs de 4 int (donc 16 octets). En pratique, cela signifie que la boucle vectorisée peut lire 1, 2 ou 3 int supplémentaire. Cela pourrait causer un dépassement de tableau et donc un 'segfault'. Un bon compilateur ne fera pas cela.

    Remarque: Le fait que les indices lus soient tous inférieurs à n n'a pas d'importance car, du point de vue du compilateur, l'argument n n'indique pas la taille du taille du tableau. Par exemple, si l'utilisateur est certain que son tableau contient au moins une fois la valeur, il pourrait décider d'utiliser n=INT_MAX.

    J'imagine qu'ICC fait quelques tests supplémentaires sur les alignements des pointeurs dans son implémentation de std::find(). Cela entraîne évidemment un petit surcoût qui peut ne pas être négligeable quand n est petit. C'est une information que le compilateur ne possède généralement pas (sauf inlining ou analyse inter-procedurale).

    Il ne faut pas non plus oublier que pour respecter les conventions d'appels, les codes vectorisés doivent aussi sauver et restaurer plus de registres (push/pop dans la pile). C'est un autre surcoût qu'il faut prendre en compte pour décider si la vectorisation est intéressante.

    PS: Dans ton benchmark, toutes les fonctions sont dans le même fichier. Il n'est pas impossible qu'ICC réussisse à optimiser std::find en inlinant systématiquement tout les appels de fonctions (donc potentiellement plus d'info sur n et sur l'alignement des données). Obtiens tu les même perfs quand find_int_cpp() est compilé dans un fichier séparé?