从小米10发布来看编译优化

这篇文章的起因是有人跨界要来锤桌面CPU :

看到新闻的第一感觉就是你在侮辱我的智商,第二感觉就是来自Windows程序员的愤怒。

准备

通过Google搜索了FFT+AGM+PI,最终确认小米用的是这个代码:http://www.kurims.kyoto-u.ac.jp/~ooura/pi_fft.html。下载后大概是这样的:

这是win32bin下面的预编译好的exe。   

win32bin/
        Makefile         : - for intel C++ compiler
        pi_cs.exe        : PI Calculation Program II
        pi_cs_thread.exe : - use FFT level threads
        pi_cw.exe        : PI Calculation Program III
        pi_cw_thread.exe : - use FFT level threads
        dgt_div.exe      : data converter

微博发的视频太糊了,但是隐约能看到用的是pi_ca.exe。总的来说一共有3个版本的算法,每个又有多线程版本,所以一共是6个 exe。如下:

    pi_fftca.c     : PI Calculation Program I   - standard version
                     -- use rdft() in "fft*gx.c"
    pi_fftcs.c     : PI Calculation Program II  - memory save version
                     -- use rdft() in "fft*g_hx.c"
    pi_fftcw.c     : PI Calculation Program III - memory swap version
                     -- use rdft() in "fft*g_hx.c"

ca是标准版,cs和cw是内存优化版,可以使用更少的运行内存(2001年内存很宝贵)。同样计算1000万位(实际是2289万位),ca占用218M,cs占用150M,cw占用58M。一般情况下来说,内存占用比较多的会跑的更快一些,空间换时间是编程的经典优化,这里小米用的是ca版也是没问题的。

对比

首先这是我的电脑的运行时间29s:

我的CPU是AMD3700X,虽然小米是和Intel8550U对比,但是都是比较的单核性能差距不会很大。众所周知AMD的单核性能一直要比Intel弱。8550U最高睿频是4.0G,3700X我这边是4.3G,就加个10%当作8550U的运行时间:32s。

先来进行下理论对比: 骁龙865使用的是高通Kryo 585CPU组合  1x Kryo 585 Prime @ 2.84GHz + 3x Kryo 585 Gold @ 2.42GHz + 4x Kryo 585 Silver @ 1.80GHz。单从CPU主频来看,小米10的36s肯定是优化后的结果。

我的猜测是,小米派了工程师对FFT+AGM算法进行一些指令优化,因为2001年的时候应该还没有所谓的SIMD Vectorized指令优化。看看Windows平台在加上最新的AVX2和AVX512指令优化和并行后的水平吧 (http://www.numberworld.org/y-cruncher/):

2500万位只需要1.6s。

为什么小米的会跑了90多秒?

回到刚刚下载的pi_fftc6,在代码里面,作者很明确的说了编译命令:

/*
---- calculation of PI(= 3.14159...) using FFT and AGM ----
    by T.Ooura

Example compilation:
    GNU      : gcc -O6 -ffast-math pi_fftcs.c fftsg_hx.c -lm -o pi_css
    SUN      : cc -fast -xO5 pi_fftcs.c fftsg_hx.c -lm -o pi_css
    Microsoft: cl /O2 /G6 pi_fftcs.c fftsg_hx.c /Fepi_css.exe
    ...
    etc.
*/

我来示范下在VIsualStudio2019中怎么用命令行编译:

1. 打开开发者命令提示

2.cd xxxxxxx\pi_fftc6(你的源码解压路径)

3.cl /O2 /G6 pi_fftcs.c fftsg_hx.c /Fepi_css.exe

4.开始编译,其中/G6是个弃用的选项

 

如果按照上面去编译,那运行结果是和我一样的。但这个结果显然不符合小米10发布会的要求。

首先说下,下载里面win32bin自带的pi_cs.exe的运行时间确实在100s左右:

明明是100多秒的,为啥同样的代码同样机器我编译后就不到30s了。原因是:编译器更新很多代了。所以我估计小米工程师在编译的时候要么下载了2001年的编译器,要么把编译命令的 /O2改成了/Od,也就是禁用编译器优化。这个/O2即对应项目管理器里面的C/C++ 的优化页面的第一个选项,如下:

通常我们VS默认的配置debug里面就是使用的/Od。

开始锤

如果小米10用的是下载压缩包自带的pi_cs.exe来进行比较的,那我最多认为他的工程师不够严谨。但是,小米不但自己编译了pi_ca.exe,而且还故意编译出一个慢速的版本来对比。真是怎么low怎么来:

既然这样,我也建议Windows工程师要么别用小米手机,要么就转行做安卓开发。开发一个落伍的平台,那不是自己给自己找罪受嘛。

最后:

FFT+AGM是通过迭代来计算小数点后的数,在运行pi_cs.exe时,需要输入FFT的长度,这不是计算的位数,小数点后位数的计算方式大概在这里pi_fftcs.c:

测试时输入:4194304,目标计算位数是:16777216,实际计算的位数是:22890416。

这一篇先这样,过段时间后再写一篇文章分析下/O2后在汇编上的实际优化有哪些。

猜你喜欢

转载自blog.csdn.net/luoyu510183/article/details/104327013