l4m2 发表于 2014-7-1 07:18:27

整数开根号果真慢过浮点?

org 100h
mov esi,0xfffffff
ee:
lea eax,
cvtsi2sd xmm0,eax
addsd xmm0,
sqrtsd xmm1,xmm0
cvttsd2si eax,xmm1
dec esi
jnz ee
ret
db $1e8-$ dup 0
yy:
dq 2147483648.0
时间2.6s

http://bbs.emath.ac.cn/thread-1207-2-1.html好像都更慢,有更快的吗

l4m2 发表于 2014-7-1 07:24:29

至1fffffff是4.84
至fffffffff是37.08

l4m2 发表于 2014-7-1 07:30:36

空转2^32 = 3.83

l4m2 发表于 2014-7-1 08:15:44

更严重的是

//这个程序计算从1到0xFFFFFFFF的所有数的平方根,并全部打印
#include <stdio.h>
#include <stdlib.h>

int main(int argc, char** argv)
{
    register unsigned int num = 1;
    register unsigned int root = 1;
    register unsigned int square = 0;


    for( ; ; root++)
    {
      square += root << 1;
      square--;

      for( ; ; )
      {
            if(num == square)
            {
#ifdef __DEBUG__
                printf("square root of %d is %d\n", num, root);
#endif
                num++;
                break;
            }

#ifdef __DEBUG__                        
            printf("square root of %d is %d\n", num, root-1);
#endif                        
            num++;

            if(num == 0xFFFFFFFF)
            {
                return 0;
            }
      }
    }

    return 0;
}


org 100h
xor eax,eax
xor ecx,ecx
xor edx,edx
s1:
lea edx,
s2:
;do
inc eax
dec edx
jnz s2
inc cx
jnz s1
ret            
跑了一分多钟(接近2)没结果

l4m2 发表于 2014-7-1 08:18:21

org 100h
xor eax,eax
xor ecx,ecx
xor edx,edx
s1:
lea edx,
s2:
;do
inc eax
dec edx
jnz s2
inc cx
jnz s1
ret            是3.78,上一层楼的不对

gxqcn 发表于 2014-7-2 07:56:28

平方根算法主要有牛顿迭代法、二分查找法,对于整型来说,还有一种“移位相减”的硬件算法。

对于计算机来说,要看运行的平台,比如 CPU 支持哪些指令集,以及相关指令的时钟数;
还要看需求,比如说,是否短时间内反复调用?cache 是否对其有影响?
另外,对于某些特殊范围的入参,还可以有更快的版本,比如说,对于 \(\text{4 ~ 15}\) 内的 \(n\),用 \((n+15)\gg3\) 即可快速获取其平方根。

liangbch 发表于 2014-7-3 11:06:09

1楼的程序核心部分使用了SSE2指令SQRTSD,这条指令属于浮点指令,和普通的浮点指令比,SSE2指令的操作数在MMX或者XMM中,而普通浮点指令的操作数在浮点数栈中进行。

下面列出这段代码中使用的几条SSE2指令。

cvtsi2sd:
   Convert Dword Integer to Scalar Double-Precision FP Value
ADDSD:
    Add Scalar Double-Precision Floating-Point Values
CVTTSD2SI:
   Convert with Truncation Scalar Double-Precision FP Value to Signed Integer
SQRTSD:
   Compute Square Root of Scalar Double-Precision Floating-Point Value

l4m2 发表于 2014-7-3 11:22:47

liangbch 发表于 2014-7-3 11:06
1楼的程序核心部分使用了SSE2指令SQRTSD,这条指令属于浮点指令,和普通的浮点指令比,SSE2指令的操作数在M ...

程序是我写的,这个我懂(当然作为补充也无妨):)

l4m2 发表于 2014-7-3 11:24:55

liangbch 发表于 2014-7-3 11:06
1楼的程序核心部分使用了SSE2指令SQRTSD,这条指令属于浮点指令,和普通的浮点指令比,SSE2指令的操作数在M ...

不过你如果能分析lea和add的妙处那最好
lea eax,
cvtsi2sd xmm0,eax
addsd xmm0,;2147483648.0

liangbch 发表于 2014-7-3 13:21:06

l4m2 发表于 2014-7-3 11:24
不过你如果能分析lea和add的妙处那最好

这又什么难以理解的?
cvtsi2sd 要求源操作数是带符号数,故当操作数>=$2^31$, cvtsi2sd不能按预期的方式工作。代码“lea eax,”将被开方数减去$2^31$,转化为浮点数后,使用代码“addsd xmm0," 又加上$2^31$来恢复到原始值。这样,当被开方数大于$2^31$时,也能工作了。
页: [1] 2
查看完整版本: 整数开根号果真慢过浮点?