【问题标题】:Fastest assembly code for finding the square root. Explanation needed [closed]求平方根的最快汇编代码。需要解释[关闭]
【发布时间】:2018-03-03 17:03:00
【问题描述】:

我目前正在用 C 语言编写一个需要找到数十亿平方根的程序。我查找了哪些已知代码可以更快地找到平方根,并遇到了这个看似最快的代码。 https://www.codeproject.com/Articles/69941/Best-Square-Root-Method-Algorithm-Function-Precisi

double inline __declspec (naked) __fastcall sqrt(double n)
{
    _asm fld qword ptr[esp + 4]
    _asm fsqrt
    _asm ret 8
}

我对汇编语言了解不多,所以有人可以解释一下这段代码在算法上的作用以及这些关键字的含义吗?

【问题讨论】:

  • 它是“fsqrt”操作码在cpu/fpu微码中实现的一种算法。
  • 绝对不是最快的代码(甚至接近)。只有三个指令,一个是返回。基本无话可说。
  • 在有可用库函数的情况下使用内联汇编时要非常非常小心。编译器对程序集是否有意义进行零检查。你通过说“我知道我在做什么并且我可以做得比你做得更好”来打败编译器提供的所有好处。今天的编译器非常擅长优化代码,你在网上找到的一些代码几乎不可能比你的编译器做得更好。 (组装错误的不利影响总是超过性能的任何边际提升)
  • @MargaretBloom 你试过使用它吗?它实际上非常准确且超快。我已经将它与标准 sqrt 函数进行了比较,还创建了一种二进制搜索方法,但这个方法更快。
  • 即使旧的 x87 fsqrt 对您的情况来说是最快的,并且差异会很大(用这个替换 lib sqrt),那么您可能处于整个循环可能会受益于正确重写为程序集,因为您发布的函数很难与其他计算很好地配合,因为它将内存中的值加载到 FP 堆栈中,而如果它与循环中的其他计算集成,它可能会该值已经在 FP 堆栈上,节省了一次内存写入+读取。但您肯定可以从矢量化和 SSE 使用中获得更多收益。

标签: c assembly root inline-assembly sqrt


【解决方案1】:

这是标准 sqrt 函数的 Microsoft 特定 naked fast call

有关详细信息,请查看 Microsoft 文档。

naked storage-class 属性是 Microsoft 对 C 语言的特定扩展。对于使用裸存储类属性声明的函数,编译器会生成没有序言和结语代码的代码。您可以使用此功能使用内联汇编代码编写自己的序言/结语代码序列。裸函数在编写虚拟设备驱动程序时特别有用。 请参阅:Naked functions

__fastcall 调用约定指定函数的参数应尽可能在寄存器中传递。此调用约定仅适用于 x86 架构。看一眼: __fastcall

__fastcall 是很久以前由 Microsoft 推出的。通常,fastcall 调用约定在寄存器中传递一个或多个参数,从而减少调用所需的内存访问次数。使用片上缓存,在寄存器中传递东西的收益并不像过去那样大。 而__stdcall 现在可能实际上更快了。

【讨论】:

    猜你喜欢
    • 2010-10-01
    • 1970-01-01
    • 1970-01-01
    • 2014-09-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多