2009-04-21 6 views

Répondre

3
#if defined(_MSC_VER) 
// visual c 
#elif defined(__GCCE__) 
// gcce 
#else 
// unknown 
#endif 

Mes compétences en assembleur en ligne sont rouillés, mais il fonctionne comme:

__asm 
{ 
// some assembler code 
} 

Mais il suffit d'utiliser rdtsc vous pouvez simplement utiliser intrinsics:

unsigned __int64 counter; 
counter = __rdtsc(); 

http://msdn.microsoft.com/en-us/library/twchhe95.aspx

+0

Merci! Existe-t-il une variante linux pour intrinsèques rdtsc? –

2

Il existe une macro _MSC_VER dans VC++ qui est décrite comme "spécifique à Microsoft" dans MSDN et n'est probablement pas définie lorsque le code est compilé sur d'autres compilateurs. Vous pouvez utiliser #ifdef pour déterminer quel est le compilateur et compiler un code différent pour gcc et VC++.

#ifdef _MSC_VER 
    //VC++ version 
#else 
    //gcc version 
#endif 
2

Utilisation de l'instruction RDTSC a directement quelques inconvénients graves:

  • Le TSC n'est pas garanti à synchroniser sur tous les processeurs, donc si votre thread/processus émigre d'un noyau de CPU à l'autre le TSC peut sembler " warp "avancer ou reculer dans le temps sauf si vous utilisez une affinité de thread/processus pour empêcher la migration.
  • Il n'est pas garanti que le TSC progresse à un débit constant, en particulier sur les PC dont la gestion de l'alimentation est activée ou la fonction "Rampe d'horloge C1" activée. Avec plusieurs processeurs, cela peut augmenter l'inclinaison (par exemple, si vous avez un thread qui tourne et un autre qui est en train de dormir, un TSC peut avancer plus vite que l'autre). L'accès direct au TSC ne vous permet pas de tirer parti de HPET.

via une interface de minuterie OS est mieux, mais il peut encore avoir quelques-uns des mêmes inconvénients en fonction de la mise en œuvre:

également Notez que Microsoft Visual C++ ne prend pas en charge l'assemblage en ligne lors du ciblage des processeurs 64 bits, d'où le __rdtsc() intrinsèque que Virne a souligné.

+1

Ou même mieux utiliser un composant de bibliothèque indépendant de la plate-forme comme http://www.dre.vanderbilt.edu/Doxygen/Stable/ace/classACE__High__Res__Timer.html – lothar

+0

TSC a ses inconvénients, comme décrit, mais il a aussi ses avantages. Il est extrêmement rapide (20-30 horloges), alors que tous les autres mécanismes tels que le HPET impliquent de voyager dans l'anneau 0 et coûtent donc 1000 clockticks ou plus. C'est précis, alors que les outils OS standard offrent souvent la granularité de 10 ms. HPET n'est pas disponible sur de nombreux systèmes, et quand c'est le cas, il peut seulement être accessible au superutilisateur. Ne me demandez pas pourquoi - allez chercher la boîte Linux la plus proche et vérifiez les privilèges sur/dev/hpet. – user434507

+0

En ce qui concerne la synchronisation, elle est généralement synchronisée entre les cœurs sur les Intels de bureau (pas sûr sur les Intels mobiles) et, sur les AMD, vous pouvez restreindre la migration entre les cœurs en modifiant l'affinité processeur de votre thread. – user434507

2

Le problème spécifique OP a de côté: je l'ai trouvé un moyen de définir une macro qui fonctionne pour les deux versions de syntaxe:

#ifdef _MSC_VER 
# define ASM(asm_literal) \ 
     __asm { \ 
      asm_literal \ 
     }; 
#elif __GNUC__ || __clang__ 
# define ASM(asm_literal) \ 
     "__asm__(\"" \ 
      #asm_literal \ 
     "\" : :);" 
#endif 

Malheureusement, parce que le préprocesseur strips newlines before macro expansion, vous devez entourer chaque déclaration d'assemblage avec cette macro .

float abs(float x) { 
    ASM(fld  dword ptr[x]); 
    ASM(fabs    ); 
    ASM(fstp dword ptr[x]); 

    return x; 
} 

Mais s'il vous plaît noter que GCC et clang use AT&T/UNIX assembly synax mais MSVC Intel syntaxe usées assemblage (n'a pas pu trouver aucune source officielle bien).Mais heureusement, GCC/clang peut aussi être configured to use Intel syntax. Soit utiliser __asm__(".intel_syntax noprefix");/__asm__(".att_syntax prefix"); (soyez sûr de réinitialiser les changements car cela affectera tout l'ensemble généré à partir de ce point, même celui généré par le compilateur à partir de la source C). Cela nous laisse avec une macro comme ceci:

#ifdef _MSC_VER 
# define ASM(asm_literal) \ 
     __asm { \ 
      asm_literal \ 
     }; 
#elif __GNUC__ || __clang__ 
# define ASM(asm_literal) \ 
     "__asm__(\".intel_syntax noprefix\");" \ 
     "__asm__(\"" \ 
      #asm_literal \ 
     "\" : :);" \ 
     "__asm__(\".att_syntax prefix\");" 
#endif 

Ou vous pouvez aussi compiler avec GCC/clang en utilisant le drapeau -masm=intel, qui commute la syntaxe à l'échelle mondiale.

Questions connexes