floatdouble和double偏移量的问题

float和double一样快吗?float和double一样快吗?一个小时头66百家号我记得世纪之初的时候,某本古老的书上有这么一句话,大概是这个意思,无论是float还是double,在CPU内部都是转换为80位浮点数运算的,因此float和double其实是一样快的。但是时代变化太快,这句话现在还对不对呢?写了个程序验证一下。使用的是Visual C++ 2015 Update 2,编译为x64架构。为了避免调试器的干扰,直接使用Ctrl+F5运行。程序如下:// realspeed.cpp : 定义控制台应用程序的入口点。//#include &stdafx.h&#include &stdio.h&#include &windows.h&#define veclen 1048576float vec1[veclen];float vec2[veclen];float vec3[veclen];double dvec1[veclen];double dvec2[veclen];double dvec3[veclen];int main(){Debug下Ctrl+F5直接运行:Release下Ctrl+F5直接运行:可以看到,在Release编译下,float比double快得多,而在Debug编译下则几乎没有差别。这是为什么呢?在这里我们设置了个断点,进行一下反编译——Debug下的反编译:// realspeed.cpp : 定义控制台应用程序的入口点。Release下的反编译:// realspeed.cpp : 定义控制台应用程序的入口点。可以看到,现在早已过了x87 FPU的年代,编译器并没有使用FPU指令,而是使用的SSE指令。Debug编译下,为了调试方便,将每一个循环都完整表现出来了(循环计数为100000h,即1048576),并且使用了movss/mulss和movsd/mulsd这两组标量指令,速度当然差不多。而Release编译下,则将循环计数精简为20000h(8576/8)和40000h(8576/4),并且使用了movups/mulps和movups/mulpd这两组矢量指令,每次循环内进行2次运算,总计进行40000h(8576/4)和80000h(8576/2)次运算。由于SSE寄存器是固定的128位宽,每次只能放置4个32位宽的float或2个64位宽的double数据,因此使用float的话,只需要进行1/4次运算,而使用double的话,则需要进行1/2次运算。结论就是:对于标量运算,float和double没有显著差别,而对于矢量运算,float比double要快。因此,在计算量庞大的图形运算中,通常使用float而不是double以提高运算速度。上面演示的是四则运算,编译器自然有充足的弹性进行优化。那如果是像exp、log这样的math.h函数,编译器怎么优化呢?比如下面的代码:// realspeed.cpp : 定义控制台应用程序的入口点。//#include &stdafx.h&#include &stdio.h&#include &windows.h&#include &math.h&#define veclen 1048576float vec1[veclen];float vec2[veclen];float vec3[veclen];double dvec1[veclen];double dvec2[veclen];double dvec3[veclen];int main(){我们看一下Release反汇编就知道了。Release反汇编如下:// realspeed.cpp : 定义控制台应用程序的入口点。可以看到,编译器并没有调用logf和log函数,而是调用了__vdecl_logf4和__vdecl_log2函数。因此,即使是使用了math.h中的数学函数,仍然可以实现矢量运算优化。本文由百家号作者上传并发布,百家号仅提供信息发布平台。文章仅代表作者个人观点,不代表百度立场。未经作者许可,不得转载。一个小时头66百家号最近更新:简介:做你想做的,做错了算百度的作者最新文章相关文章鍗氬?鍒嗙被锛

我要回帖

更多关于 intfloatdouble 的文章

 

随机推荐