Lorsqu'une nouvelle génération de processeurs est disponible, la plupart des sites Web signalent que les moteurs de jeu et les programmes doivent être optimisés pour le nouveau matériel. Je ne comprends pas trop pourquoi. Un processeur a généralement une architecture qui définit le type de jeu d’instructions qu’il utilise. Celui que nous utilisons tous aujourd'hui est amd_x86_64. Pourquoi un programme ou un compilateur doit-il être mis à jour si tous les processeurs utilisent cette même architecture? Certes, il existe dans le pipeline du nouveau processeur des fonctionnalités qui optimisent l'exécution du code machine, mais pourquoi faudrait-il modifier le code machine lui-même si l'architecture ne le faisait pas?
39
Réponses:
Parce que différentes générations de la même architecture peuvent avoir différents jeux d'instructions .
Par exemple, les extensions Streaming SIMD constituent probablement le jeu d'instructions x86 le plus connu. Pourtant, et malgré l'existence d'une architecture x86, il existe des interfaces SSE, SSE2, SSE3 et SSE4.
Chacune de ces générations peut inclure de nouvelles instructions offrant des moyens plus rapides d'effectuer certaines opérations. Un exemple intéressant pour les jeux pourrait être les instructions du produit scalaire.
Ainsi, si un moteur de jeu est compilé pour une génération précédente d'une architecture, il ne supportera pas ces nouvelles instructions. De même, il peut être nécessaire d'optimiser le moteur pour les nouvelles instructions; SSE4 , par exemple, prend en charge les instructions de produit point qui fonctionnent sur des données de type tableau de structures. Une optimisation qui pourrait tirer parti de ces nouvelles instructions consisterait à changer la disposition de vos données en tableau de structures.
la source
La réponse de Maximus est correcte, je veux juste donner un autre morceau de l'histoire:
Le matériel lui-même change de la même manière que vous devez modifier la manière dont vous codez, quelles que soient les nouvelles instructions introduites.
L'augmentation ou la diminution des quantités de cache signifie que vous devez vous préoccuper moins de l'optimisation / de l'invalidation du cache. Plus de cache signifie que, avec de petites données, vous pouvez vous concentrer moins sur la contiguïté des données pour éviter les problèmes de performances. Moins de cache signifie que cela pourrait être un problème, et très peu de cache signifie que, avec de grandes structures de données, cela n'aura aucune importance.
De nouveaux niveaux de cache signifient que vous devez réfléchir davantage à la manière dont vous organisez des ensembles de données encore plus volumineux (L1, L2, L2, L3, L4).
Plus de cœurs signifie que vous devez réfléchir à la manière dont vous allez améliorer les applications multithreads et à la manière dont votre application évolue dans un environnement multi-processus.
Des horloges plus rapides signifient que vous devez penser davantage à la latence de la mémoire qu'à la vitesse de calcul du processeur, qui constitue un goulot d'étranglement pour votre système.
Le nombre de FPU sur un système peut ne plus correspondre au nombre d'ALU entières par cœur (AMD avait / avait une telle architecture).
Le nombre de cycles d'horloge nécessaires pour calculer une opération peut être diminué ou augmenté.
Le nombre de registres disponibles a changé.
Tous ces éléments ont un impact très réel sur les performances des programmes, qui ont émis des hypothèses sur l’architecture sous-jacente d’un matériel antérieur avec le même ISA, qu’elles soient positives ou négatives.
la source
pdep
prend 1 cycle sur Intel mais 6 sur Ryzen, donc ne voulez pas l'utiliser sur Ryzen.c[i] = a[i] OP b[i]
(c.-à-d. 2 charges et 1 magasin par opération), de sorte que les temps sont dominés par la bande passante mémoire en raison de la très faible intensité de calcul. La taille du tableau n'est pas affichée, donc IDK si elle convient à L1D. (gcc4.9 -Ofast
très probablement, ces boucles sont vectorisées automatiquement, de sorte que vous ne mesurez même pas le coût des opérations scalaires normales dans le cadre d’un code entier complexe). La première ligne de cette page est IMPORTANT: des commentaires utiles ont révélé que certaines de ces mesures sont sérieusement défectueuses. Une mise à jour majeure est sur le chemin .Même au-delà de changements brusques tels que la prise en charge de nouvelles instructions, les fabricants de microprocesseurs modifient constamment leurs conceptions pour améliorer les performances. Chaque nouvelle conception peut avoir des performances relatives différentes pour chaque instruction ou technique. Vous avez peut-être écrit du code sans embranchement soigneusement optimisé pour le modèle X, mais le modèle Y dispose d'un prédicteur de branche amélioré qui réduit la pénalité de prédiction erronée pour la version sans code du code (ce qui libère également un registre pouvant être utilisé ailleurs) . Peut-être que le modèle Y prend en charge un plus grand parallélisme d'une certaine instruction à latence élevée, de sorte qu'une boucle déroulée de cette instruction permet d'obtenir un meilleur débit, alors que sur le modèle X, une séquence plus courte était préférable.
Tout problème peut être résolu de nombreuses manières et chaque programme est une collection imbriquée de compromis et d’allocation de ressources, du point de vue de l’optimisation. Même de petits changements dans la disponibilité de ces ressources ou dans le coût d'un code donné par rapport à ces ressources peuvent avoir un effet en cascade qui confère un avantage substantiel en performances à un code ou à un autre. Même si une puce mise à niveau a « plus de tout », combien beaucoup plus de chaque chose peut faire pencher la balance.
la source