fan*_*mnm 5 c c++ floating-point floating-point-conversion
我需要对已排序数字的数组进行优化的二进制搜索算法.我做了这个,发现使用float来存储数字比使用整数更快,因为最后我必须计算
(frameNumber-this->frameNumber[imin])/(this->frameNumber[imax]-this->frameNumber[imin])
Run Code Online (Sandbox Code Playgroud)
this->frameNumber[imin]是最大的frameNumber不等于,frameNumber并且this->frameNumber[imax]是最大的frame_umber .该代码用于计算两个关键帧之间的进度.frameNumber数组是静态的.我只需要对它进行一次排序.但是使用二进制搜索和上面的代码多次访问它来计算进度.
从int到float的转换花费了一些周期.然后我发现在asm中有很多fpu指令.我担心它们可能比整数慢.
所以这是问题所在.我可以将已排序的浮点数数组转换为int*并对其进行二进制搜索吗?
这意味着:
void binary_search(float key,float* array,...)
{
int key_integer=*(int*)&key;
int* array_intege(int*)array;
binary_search_for_integers(key_integer,array_integer,...);
}
Run Code Online (Sandbox Code Playgroud)
或者我的上述结论是错误的?(比如将int转换为浮点数不是那么算,或者浮点数之间的比较与整数相同?
非常感谢!
这似乎是个坏主意。正如 @rlbond 指出的那样,对浮点数据使用整数比较实际上会产生正确排序的浮点数组。(请参阅http://www.h-schmidt.net/FloatConverter/IEEE754.html以使用浮点数的二进制表示形式。)sizeof(int32_t) == sizeof(float)在使用之前请检查这一点。
像这样的 hack 并不是真正需要的。 在现代硬件上,float比较并不比比较贵多少。int(Intel Haswell:ucomiss为 1 uop,每周期吞吐量为 1。与内存操作数相比,为 2 uops,但没有微融合。并且它不能像宏融合一样cmp/jcc)但是,FP add/sub 和 FP mul 有比其整数等价物有更高的延迟,并且吞吐量更低。float将整个数组转换为写入数组似乎很愚蠢,因为您想在末尾使用最小值和最大值进行一些 FP 数学运算。
加载并转换 int 到浮点指令(x86 cvtsi2ss(有符号整数 2 标量单))与普通加载 ( movss) 大约一样快,并且占用相同的代码空间。
如果您的数据最初是整数,并且您只使用其中的一部分,请使用int(避免转换为以后不再需要的值)。如果您确实访问了所有数据,并且仅将数据用作浮点数,则将其存储为float. 如果您将其同时用作两者,则最好将其存储为int,因此当您将其用作整数时,速度会更快,而当您将其用作浮点数时,速度大约相同。
从您的代码示例中,您只是使用最小和最大位置的值?查找数组中的最小值和最大值比对整个数组进行排序要快得多。最小/最大甚至使用压缩最小指令进行矢量化。
许多平台没有像现代 Intel CPU 那样快的浮点运算,因此不要过度使用浮点运算。