如果您正在编写一个对延迟很敏感的应用程序,那么在C ++函数中嵌入汇编程序的限制是什么(并且通常使用C ++函数调用),如下所示:
inline __int64 GetCpuClocks()
{
// Counter
struct { int32 low, high; } counter;
// Use RDTSC instruction to get clocks count
__asm push EAX
__asm push EDX
__asm __emit 0fh __asm __emit 031h // RDTSC
__asm mov counter.low, EAX
__asm mov counter.high, EDX
__asm pop EDX
__asm pop EAX
// Return result
return *(__int64 *)(&counter);
}
(上述功能来自我看过的另一篇SO帖子)
您能否将汇编内联函数视为黑盒?你可以轻松地从汇编程序中执行的计算中检索结果吗?是否有危险您不知道当前寄存器中的变量等?它会导致比解决更多的问题,还是特定的小任务可以接受?
(假设您的架构将被修复并且已知)
编辑我刚刚发现了这个,这就是我所暗示的:http://www.codeproject.com/Articles/15971/Using-Inline-Assembly-in-C-C
EDIT2这更多的是针对Linux和x86-它只是一个普通的C ++ /汇编程序问题(或者我认为)。
答案 0 :(得分:3)
我想回答一下这个问题:
它会导致比解决更多的问题,还是特定的小任务可以接受?
当然可以!使用内联汇编程序,您可以从编译器中优化代码。它不能做部分表达式替换或任何其他花哨的优化。生成比编译器使用-O3更好的代码真的非常非常难。作为奖励,下一个编译器版本的代码变得更好(假设下一个编译器版本没有破坏它;))。
编译器通常掌握比人类大脑更广泛的范围(或者应该,以确保理智),能够在正确的位置内联正确的功能,进行部分表达式替换,使代码更有效。你永远不会在ASM做的事情,因为你的代码变得难以理解。
作为一个轶事参考,我想由Linus Torvalds this post提到有关SHA1的git实现,它在libcrypt中优于手动优化的SHA1。
事实上,我认为现在唯一合理使用内联汇编程序的方法是调用另外没有的处理器指令(你引用的处理器指令可以在linux上使用,例如clock_gettime
,至少如果你是只有在高分辨率时间计数器之后)或者你必须做一些你需要欺骗编译器的事情(例如在执行外部函数接口期间)。
在片段上和其他人说的话。特别是使用这些功能,您将获得性能损失。在内联asm中,你必须非常小心,寄存器保持在编译器假定的状态(push / pop,如上所述)。如果你正常编写代码,编译器可以注意并保留那些在寄存器中有意义的变量以及那些不适合堆栈的变量。
相信你的编译器。这很聪明。大多数时候。通过不使用内联汇编程序来考虑智能,快速算法和学习相关编译器开关(例如,启用SSE优化等)来节省您节省的时间。
答案 1 :(得分:1)
如果有问题的asm正在推动它在顶部使用的任何寄存器,那么在底部弹出它们,我认为你不用担心它是安全的。
在您的示例中,这些是__asm push EAX
和__asm pop EAX
说明。
我想,真正的答案是,你需要充分了解asm的功能,以确保你可以将其视为一个黑盒子。 :)