7
votes

Visual C ++ x64 Ajouter avec Carry

Comme il ne semble pas y avoir une intrinsèque pour ADC et je ne peux pas utiliser l'assembleur en ligne pour l'architecture X64 avec Visual C ++, que dois-je faire si je veux écrire une fonction à l'aide de l'ajout avec Carry, mais incluez-la dans un Espace de noms C ++?

(émulation avec les opérateurs de comparaison n'est pas une option. Cette ajout de 256 mégabit est critique.)


3 commentaires

Dites-nous plus sur ce "256 Megabit Ajouter". Il est fort probable que faire plusieurs ajouts à la fois à l'aide de SIMD seront considérables plus rapidement, même en considérant que des portes doivent être traitées comme une étape supplémentaire.


J'ai déjà fait ce morceau de recherche. Voir Stackoverflow.com/Questions/ 8866973 / ... .


@ JNM2 - La manière X64 semble écrire un code d'assemblage distinct et l'appeler à partir de votre fonction C ++. L'assembleur fait déjà partie de l'emballage.


3 Réponses :


7
votes

VS2010 a pris en charge intégré pour la compilation et la liaison de code écrit en montage et traduit par MASM (ML64.exe). Vous devez juste sauter à travers quelques cerceaux pour l'activer:

  • Cliquez avec le bouton droit de la souris sur le projet dans la fenêtre de la solution Explorateur, construire des personnalisations, cochez "MASM".
  • Project + Ajouter un nouvel élément, choisissez le modèle de fichier C ++ mais Nom It quelque chose.asm
  • Assurez-vous que vous avez la cible de la plate-forme X64 pour le projet. Construire + Configuration Manager, sélectionnez "X64" dans le combo "Plate-forme Solution active". S'il manque, sélectionnez et choisissez X64 à partir du premier combo. S'il vous manque, vous devrez réexécuter la configuration et ajouter une prise en charge des compilateurs de 64 bits.

    écrire code d'assemblage à l'aide de la syntaxe MASM, référence est Ici . Tutoriel de démarrage rapide est ici .

    Le squelette Pour le code d'assemblage ressemble à ceci: xxx

    et appelé de code C ++ comme ceci: xxx

    Le support complet de débogage est Disponible, vous voudrez généralement utiliser au moins la fenêtre Débogou + Windows + Registers.


1 commentaires

La solution idéale dans ce cas serait des fonctions en ligne (assemblage en ligne). L'utilisation d'un assembleur et de liaison dans les fichiers d'objet ne fera pas que ce code et 64 bits dans MSVC ne permettent pas l'assemblage en ligne. Cela signifie donc que l'OP doit écrire de nombreuses autres fonctions (que le compilateur fait probablement un bon travail avec déjà) en montage également pour éviter les appels de fonctions.



1
votes

J'ai mis en place un entier 256 bits à l'aide d'un tableau de non signé long long code> et utilisé x64 ensemble pour mettre en œuvre l'ajout avec le transport. Voici l'appelant C ++:

#include "stdafx.h"

int _tmain(int argc, _TCHAR* argv[])
{
    unsigned long long a[4] = {0x8000000000000001, 2, 3, 4};
    unsigned long long b[4] = {0x8000000000000005, 6, 7, 8};
    unsigned long long c[4] = {0, 0, 0, 0};
    c[0] = a[0] + b[0]; // 6
    c[1] = a[1] + b[1] + (c[0] < a[0]); // 9
    c[2] = a[2] + b[2] + (c[1] < a[1]); // 10
    c[3] = a[3] + b[3] + (c[2] < a[2]); // 12
    return 0;
}


1 commentaires

Désolé d'être en retard, mais la solution C ++ n'est pas correcte. Comme la simplification considère A = 01 et B = 11 avec port = 1, puis c = 01 avec port = 1 mais C



7
votes

Il y a maintenant un instrument Instinsic pour ADC Code> dans msvc: _addcarrry_u64 code>. Le code suivant

mov rdx, QWORD PTR x$[rsp]
mov r8, QWORD PTR x$[rsp+8] 
mov r9, QWORD PTR x$[rsp+16]
mov rax, QWORD PTR x$[rsp+24]
add rdx, QWORD PTR y$[rsp]
adc r8, QWORD PTR y$[rsp+8]
adc r9, QWORD PTR y$[rsp+16]
adc rax, QWORD PTR y$[rsp+24]


6 commentaires

Cette réponse nécessite une responsabilité de non-responsabilité, cette instruction ne peut être utilisée que sur les processeurs de base de la 4ème génération (HASWELL et UP). 5 à 10 ans et un numéro de téléphone de support avant de pouvoir en dépendre aveuglément pour être disponibles.


@Hanspassant Je ne suis pas capable de confirmer cela. Avez-vous une référence pour cela?


@Hanspassant, votre tort, cela fonctionne bien sur mon système de pont Ivy et cela devrait fonctionner correctement sur tous les processeurs X86-64. Avez-vous lu ma réponse? Avez-vous remarqué que le compilateur produit adc et non adcx ? J'ai mis à jour la réponse afin que vous puissiez le tester sur votre propre système (je suppose que vous pouvez en trouver un avant Broadwell) et regarder l'assemblage généré. Maintenant que j'ai édité ma question, vous pouvez me uppoter. C'est le moins que vous puissiez faire.


Eh bien, c'est bien pour moi de me tromper, ce n'est pas mon post. C'est plutôt à vous de documenter les processeurs dans le jeu "Core de la 4ème génération". Le vôtre n'est pas si vous obtenez la vieille instruction. Ne soyez pas un haswell à tout moment bientôt, je suppose. Très beau processeur BTW.


@Hanspassant, les instructions ADX ont été ajoutées à Broadwell, pas Haswell. Je possède un processeur Haswell (mais pas Broadwell) mais ce n'est pas ce que j'ai testé cela. Pourquoi est-ce que je vais documenter quels processeurs sont "noyau de la 4ème génération". Cela n'a rien à voir avec ma réponse. Peut-être la documentation d'Intlel est fausse? .


@Hanspassant, Intel a mis à jour leur documentation sur le papier blanc et Intel Guide intrinsèque . Donc j'avais raison. Leur documentation était fausse. _AddCarry_U64 ne produit que adc . Pourquoi avez-vous fait confiance à la documentation davantage que l'Assemblée? Il est temps que vous puissiez voter votre vote et vous voter.