_ftol 的优化
_ftol 是什么? 当你写 C 程序的时候,(int)float_v 就会被编译器产生一个对 _ftol 这个 CRT 函数的调用。
上个世纪听一个做 3d 的朋友提起过,用 x87 指令实现的 _ftol 会很慢,一般用整数指令提供。当时提在心里,2000 年的时候在 RISC 上做开发 (ARM 指令集) 曾经写过一些整数模拟浮点的函数,曾经写过这个转换函数,日子久了,现在也找不回来代码。不过对浮点的 IEEE 标准还是比较清楚的。去年写过一篇 浮点数的精度控制问题 的帖子放在流言中。当时已经被骂过了。
今天工作时又遇到关于浮点数的问题,再写篇 blog 吧,或许还是找骂贴 :)
懒的重写 _ftol 的整数指令版本了,google 搜了下,发现果然有人也做过。http://www.flipcode.com/cgi-bin/fcarticles.cgi?show=64008
就是这么一个函数:
int ftol(float f) { int a = *(int*)(&f); int sign = (a>>31); int mantissa = (a&((1<<23)-1))|(1<<23); int exponent = ((a&0x7fffffff)>>23)-127; int r = ((unsigned int)(mantissa)<<8)>>(31-exponent); return ((r ^ (sign)) - sign ) &~ (exponent>>31); }当是效率比较高的。我想,日子已经过去这么久了。当初朋友跟我提这个事情的事情大约是 98,99 年。上面翻出来的老帖是 01 年的。我现在的机器不错,今年新买的 P4 双核的,还是测试一下比较放心。 注:这个函数不能直接替换 CRT 中的 _ftol , CRT 的 _ftol 并不通过堆栈传递参数。 马上随手写了下面的测试程序:
#include "stdio.h" #define RDTSC _asm _emit 0x0f _asm _emit 0x31 #pragma warning (push) #pragma warning (disable: 4035) inline unsigned __int64 timestamp() { __asm RDTSC } #pragma warning (pop) int int_chop (float f) { int a = *(int*)(&f); int sign = (a>>31); int mantissa = (a&((1<<23)-1))|(1<<23); int exponent = ((a&0x7fffffff)>>23)-127; int r = ((unsigned int)(mantissa)<<8)>>(31-exponent); return ((r ^ (sign)) - sign ) &~ (exponent>>31); } int test1(float f) { return int_chop(f); } int test2(float f) { return (int)f; } int test3(float x) { int t; __asm fld x __asm fistp t return t; } void test(int t,int (*f)(float)) { int i; for (i=0;i运行结果如下: ---timing 0--- use int 4449676 (int) 4583873 use x87 1491980 ---timing 1--- use int 6097315 (int) 4603592 use x87 1662360 ---timing 2--- use int 2427691 (int) 4532759 use x87 1445269compiler 内置的 _ftol 表现不怎么样,比整数版还是慢了一倍。那个浮点版本是做参考的,虽然快,但是语义和 C 语言要求的不太一样,依赖 rounding mode 的设置。所以不推荐使用。 关于 double 向 int 转换,参考另一篇 blog :double to int 神奇的 magic number
Comments
Posted by: ninja | (9) November 6, 2008 10:59 AM
Posted by: HouSisong | (8) May 19, 2007 10:09 AM
Posted by: sods | (7) March 1, 2006 02:35 PM
Posted by: euclid | (6) February 17, 2006 01:19 PM
Posted by: analyst | (5) December 19, 2005 01:31 PM
Posted by: Cloud | (4) December 19, 2005 12:32 PM
Posted by: analyst | (3) December 19, 2005 12:45 AM
Posted by: 一个朋友(不方便留名字) | (2) December 17, 2005 08:27 PM
Posted by: 一个朋友(不方便留名字) | (1) December 17, 2005 08:23 PM