我入侵了一个下面的代码:如何制作跨平台的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