我入侵了一個下面的代碼:如何製作跨平臺的C++內聯彙編語言?
unsigned long long get_cc_time() volatile {
uint64 ret;
__asm__ __volatile__("rdtsc" : "=A" (ret) : :);
return ret;
}
它適用於G ++而不是在Visual Studio中。 我該如何移植它? 什麼是正確的宏檢測VS/g ++?
我入侵了一個下面的代碼:如何製作跨平臺的C++內聯彙編語言?
unsigned long long get_cc_time() volatile {
uint64 ret;
__asm__ __volatile__("rdtsc" : "=A" (ret) : :);
return ret;
}
它適用於G ++而不是在Visual Studio中。 我該如何移植它? 什麼是正確的宏檢測VS/g ++?
#if defined(_MSC_VER)
// visual c
#elif defined(__GCCE__)
// gcce
#else
// unknown
#endif
我的內聯彙編技能生疏,但它的工作原理是:
__asm
{
// some assembler code
}
但只使用RDTSC你可以使用內部函數:
unsigned __int64 counter;
counter = __rdtsc();
在VC++中有一個_MSC_VER宏,在MSDN中被描述爲「Microsoft specific」,並且在其他編譯器上編譯代碼時,可能沒有定義它。您可以使用#ifdef來確定它是什麼編譯器,併爲gcc和VC++編譯不同的代碼。
#ifdef _MSC_VER
//VC++ version
#else
//gcc version
#endif
使用RDTSC
指令直接有一些嚴重的缺陷:
使用操作系統計時器界面較好,但仍可能有一些依賴於實現同樣的弊端:
clock_gettime()
QueryPerformanceCounter()
而且請注意,Microsoft Visual C++在針對64位處理器時不支持內聯彙編,因此Virne指出的__rdtsc()
內在。
或者更好地使用像http://www.dre.vanderbilt.edu/Doxygen/Stable/ace/classACE__High__Res__Timer.html – lothar 2009-04-21 15:23:52
具體問題OP有題外話:我找到了一種方法來定義,對於這兩種語法版本工作的宏:
#ifdef _MSC_VER
# define ASM(asm_literal) \
__asm { \
asm_literal \
};
#elif __GNUC__ || __clang__
# define ASM(asm_literal) \
"__asm__(\"" \
#asm_literal \
"\" : :);"
#endif
不幸的是,因爲預處理器strips newlines before macro expansion,你必須圍繞這個宏觀每個彙編語句。
float abs(float x) {
ASM(fld dword ptr[x]);
ASM(fabs );
ASM(fstp dword ptr[x]);
return x;
}
但請注意,GCC和鐺use AT&T/UNIX assembly synax但MSVC usees Intel彙編語法(找不到但任何官方消息)。幸好GCC/clang也可以是configured to use Intel syntax。使用__asm__(".intel_syntax noprefix");
/__asm__(".att_syntax prefix");
(確保重置更改,因爲它會影響所有程序集從該點開始生成,甚至是由編譯器從C源生成的程序集)。這將使我們有這樣一個宏:
#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
或者你也可以用GCC /鐺使用-masm=intel
標誌,全球切換語法編譯。
謝謝! 是否有intrinsics rdtsc的linux變種? – 2009-04-21 11:12:57