在C+中嵌入汇编程序+;可以接受吗? 如果你写的应用程序非常敏感,那么在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); }

在C+中嵌入汇编程序+;可以接受吗? 如果你写的应用程序非常敏感,那么在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); },c++,performance,assembly,C++,Performance,Assembly,(以上功能来自我看到的另一个SO帖子) 你能像对待黑盒子一样对待汇编程序内联函数吗?您能从汇编程序中执行的计算中轻松检索结果吗?是否存在不知道寄存器等中当前有哪些变量的危险?它造成的问题比解决的问题多,还是可以接受特定的小任务 (假设您的体系结构将是固定的、已知的) 编辑我刚找到这个,这就是我想要暗示的: EDIT2这是针对Linux和x86的-这只是一个一般的C++/汇编程序问题(或者我是这么认为的)。如果有问题的asm将它使用的任何寄存器推到顶部,然后将它们弹出到底部,我想你不用担心 在您

(以上功能来自我看到的另一个SO帖子)

你能像对待黑盒子一样对待汇编程序内联函数吗?您能从汇编程序中执行的计算中轻松检索结果吗?是否存在不知道寄存器等中当前有哪些变量的危险?它造成的问题比解决的问题多,还是可以接受特定的小任务

(假设您的体系结构将是固定的、已知的)

编辑我刚找到这个,这就是我想要暗示的:


EDIT2这是针对Linux和x86的-这只是一个一般的C++/汇编程序问题(或者我是这么认为的)。

如果有问题的asm将它使用的任何寄存器推到顶部,然后将它们弹出到底部,我想你不用担心

在您的示例中,这些是
\u asm push EAX
\u asm pop EAX
指令


我想,真正的答案是,您需要充分了解asm的功能,以确保您可以将其视为一个黑盒。:)

我想回答以下子问题:

它造成的问题比解决的问题多,还是可以接受特定的小任务

的确如此!使用内联汇编程序,可以从编译器获得优化代码的能力。它不能执行部分表达式替换或任何其他奇特的优化。要生成比编译器使用-O3发出的代码更好的代码真的非常困难。作为奖励,代码在下一个编译器版本中变得更好(假设下一个编译器版本没有破坏它;)

编译器通常比人脑所能(或应该)掌握的范围更广,能够在正确的位置内联正确的函数,进行部分表达式替换,从而提高代码的效率。在ASM中您永远不会做的事情,因为您的代码变得非常不可读

作为一个轶事参考,我想介绍一下Linus Torvalds关于SHA1的git实现,它比libcrypt中手工优化的SHA1性能更好

事实上,我认为现在内联汇编程序唯一合理的用途是调用处理器指令,而这些指令在其他情况下是不可用的(您引用的指令在linux上是可用的,例如,
clock\u gettime
,至少如果您只使用高分辨率的时间计数器)或者,如果您必须在需要欺骗编译器的地方进行操作(例如,在实现外部函数接口的过程中)


在片段和其他人说的话上。尤其是使用这样的函数时,性能会受到影响。在内联asm中,您必须格外小心,确保寄存器保持在编译器假定的状态(如上所述的push/pop)。如果您正常编写代码,编译器可以注意并准确地保留寄存器中有意义的变量和堆栈中不适合的变量


相信你的编译器。它很聪明。大多数时候。通过不使用内联汇编程序来考虑智能、快速的算法和学习相关的编译器开关(例如,启用SSE优化等),从而节省时间。

因此,基本上确保开始时的状态是结束时的状态?如果你想从汇编程序返回一个计算结果,你会怎么做呢?是的,确保你不会弄乱状态。返回值将取决于编译器,我想,你是不是在问VisualC++?我想其他编译器可能有其他约束条件ᵩ 不,如果我的目标是Linux、ICC和G++的话。我刚刚抓取了我看到的第一个汇编函数。这可能有点太过分了,但是如果一个跳转和一个返回不会带来太大的惩罚,请考虑用纯汇编程序(在单独的编译单元中)编写汇编程序来保持代码的可移植性。通过避免内联,有时可以通过更高效的缓存利用率来改善延迟。不过,这在嵌入式平台上更为重要。当然,你可以说,编译器不可能在所有方面都出类拔萃。因此,为了弥补它可以处理的各种情况,可能有许多方面,对于一个小的特定任务,程序员可以编写更少的asm指令?@user997112您考虑了哪些情况?考虑到所有与数字有关的事情,你可能无法削减它。还要注意的是,我交换了引用,我原来的引用实际上包括内联ASM。我没有任何想法,但如果能够找出编译器是否存在任何不好的地方,它肯定会很有用。当然,您可以随时查看ASM输出(大多数编译器在输出目录中都有一个命令行标志来保持这一点)并与您将要编写的内容进行比较。确保使用-O3进行比较。祝您好运找到您的代码;)[确保启用行注释]实际上很少有人能比编译器做得更好的地方。您在示例中使用的编译器具有用于我们可能需要的所有“有趣”指令的编译器内部函数,包括读取CPU的性能计数器。常规函数中内联汇编的一个问题是,它会干扰编译器对周围代码的优化,从而难以实现净增益。当然,asm代码保证了代码的零可移植性。