c++ - 在 C++ 中嵌入汇编器可以接受吗?

标签 c++ performance assembly

如果您正在编写一个对延迟非常敏感的应用程序,那么在 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);

}

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

您能否将汇编程序内联函数视为黑匣子?您能否轻松地从汇编程序中执行的计算中检索结果?是否存在您不知道寄存器等中当前有哪些变量的危险?它导致的问题多于解决的问题,还是对于特定的小任务来说是可以接受的?

(假设您的架构将被修复并为人所知)

编辑我刚发现这个,这就是我要暗示的:

http://www.codeproject.com/Articles/15971/Using-Inline-Assembly-in-C-C

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

最佳答案

我想回答子问题:

Does it cause more problems than solve, or is it acceptable for specific small tasks?

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

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

作为轶事引用,我想 this post由 Linus Torvalds 撰写,与 SHA1 的 git 实现有关,它优于 libcrypt 中手动优化的 SHA1。

事实上,我认为现在唯一合理使用内联汇编程序的是调用处理器指令,否则这些指令是不可用的(你引用的那个是可用的,例如在 linux 上作为 clock_gettime,至少如果你只是在一个高分辨率的时间计数器之后)或者如果你必须在需要欺骗编译器的地方做一些事情(例如在外部函数接口(interface)的实现过程中)。


关于片段和其他人所说的。特别是对于这样的功能,您会受到性能损失。在内联 asm 中,您必须格外小心,确保寄存器保持编译器假定的状态(push/pop,如上所述)。而如果您正常编写代码,编译器会注意并准确地保留那些在寄存器中有意义的变量和那些不适合堆栈的变量。

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

关于c++ - 在 C++ 中嵌入汇编器可以接受吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13827850/

相关文章:

c++ - 如何在 Linux 中调用 "cpuid"?

assembly - 在 ml64 中的 xmm 和通用寄存器之间移动四字?

Java递归使用jsr指令

c++ - 使用 C++ 和 DDS 编写的 CMAKE 编译代码

c++ - 创建组合框的 9x9 网格时的警告

performance - 使用部分 RowKey 时是否会对 Azure 表存储的查询建立索引?

c# - 为什么绘制到 OnPaint 图形比图像图形更快?

c++ - 如何在不同文件中使用嵌套命名空间?

c++ - 数据库有问题

r - 提高数据表日期+时间粘贴的性能?