技术宅的结界

 找回密码
 立即注册→加入我们

QQ登录

只需一步,快速开始

搜索
热搜: 下载 VB C 实现 编写
查看: 331|回复: 2
收起左侧

【杂谈】世上常有尴尬事之负优化篇

[复制链接]

985

主题

2162

帖子

5万

积分

用户组: 管理员

一只技术宅

UID
1
精华
197
威望
261 点
宅币
15934 个
贡献
30898 次
宅之契约
0 份
在线时间
1514 小时
注册时间
2014-1-26
发表于 2017-8-7 07:48:28 | 显示全部楼层 |阅读模式

欢迎访问技术宅的结界,请注册或者登录吧。

您需要 登录 才可以下载或查看,没有帐号?立即注册→加入我们

x
世上常有尴尬事:
·使用了GPU加速,结果性能还不如CPU处理的(gpujpeg, libjpeg-turbo);
·使用了多线程加速,结果CPU使用率上去了但性能却还不如单线程的(7z);
·使用了SIMD指令集加速,结果性能还不如FPU的浮点处理(这里我就不说了)。
·使用了非阻塞套接字,然后无任务状态下CPU使用率100%的……

    关于第一条:本想着大量处理JPG图像将其解压为BMP,然后绘制到窗口上的。一开始用了gpujpeg,编译需要装CUDA,装上调试,1000张1080p的JPG图像,每张200K左右,解压总共需要8秒。作为对比,传统libjpeg的解压速度是16秒解压完;用Windows的COM组件解压,则需要20秒。

    本来觉得8秒已经够快了吧,但发现用libjpeg-turbo则更快,只需要5秒。后面仔细检查了情况,发现是如下原因:

    jpg格式的压缩为霍夫曼压缩+DFT压缩。它是先将原图进行DFT处理,切去频率大的部分,然后再把得到的数据用霍夫曼树进行压缩(类似于zip那样的算法),单张图霍夫曼压缩的部分只能用CPU解,因为不能并行处理;而DFT压缩的解压虽然用GPU或许会更快,但你要用GPU处理图像,你必须先把图像上传到显存,处理完之后,你还要再把它从显存上下载下来。总体下来就慢了。

    libjpeg-turbo用SIMD指令集进行DFT变换,不需要将JPG文件的内容上传到显存,也不需要从显存下载处理好的图像。SIMD指令集的加速效果还是十分显著的,作为对比的FPU处理方式就慢得多了。从libjpeg与libjpeg-turbo的解压速度的直观比较上来看,SIMD指令集似乎是比FPU指令集快4倍的(这也是预期的效果)。

    关于第二条:用7z压缩一个超级大的玩意儿,比如一个30GB的BDMV镜像,这玩意儿本身就很难被压缩,然后我弄了4个线程去压缩它,压缩选项是极限压缩,固实设定是完全固实,字典大小、单词大小被我设置到最大,然后压缩快结束的时候,内存占了快31G,整体压缩比98%,相当于没压。整体花费了多少时间我记不太清楚,但总之那会儿我电脑都没得玩,只能躺床睡觉。第二天,我用7z压缩一个40GB的BDMV的镜像,压缩比设置还是一样,但线程被我调到单线程。于是内存占用差不多5G左右,最后压缩完,整体上,感觉和上次那个30GB的耗时差不多……

    或许各种不定因素很多吧,但其实我觉得压缩文件本身就不是能进行并行处理的事情,尤其是非常在意压缩比的情况(其实压缩BDMV不需要在意压缩比,但我习惯了设置那样的压缩比来压缩)。它霍夫曼数算法并没有什么能进行并行处理的地方,就算是给字典添加单词,同时对字典操作的线程也只能有一个,而收集单词的时候,你有可能遇到信息熵很大的文件,那就每个没遇到的数据都是单词,多线程处理的话似乎意义非常小。只有在大量压缩小文件的时候,我觉得多线程处理才会有加速效果。

    关于第三条:这是某人打算用它来实现圆周率10000位的运算……好了,具体我不说了,大家都懂的。计算圆周率根本用不着浮点数运算。

    关于第四条:咳咳……这是我自己的锅。其实我写的那个玩意儿可以保证在访问数据量特别大、同时进行几万个长连接的时候也能做到不搞爆堆并且都处理得过来。但为了实现这种效果,我不让它切时间片,它要是切时间片了,可能就会影响效率……结果就是在闲置的时候它也完全不usleep(0)结局可想而知。

    其实应该先判断有没有任务要做,都没有了,那就usleep(0)。不能滥用usleep(0)也不能不用,根据不同的系统,要讲究不同的优化方式。尤其是Windows的时间片是1毫秒,这点其实更应该尽量多发挥单线程的优势——切换上下文频率低,CPU负担小。

34

主题

129

帖子

6810

积分

用户组: 管理员

UID
77
精华
11
威望
112 点
宅币
6273 个
贡献
129 次
宅之契约
0 份
在线时间
83 小时
注册时间
2014-2-22
发表于 2017-8-9 08:44:03 | 显示全部楼层
最常见的负优化:“我比编译器牛逼”系列。
很多人用ASM写性能密集型程序,结果最后发现,执行效率还不如用C写(的程序)。

985

主题

2162

帖子

5万

积分

用户组: 管理员

一只技术宅

UID
1
精华
197
威望
261 点
宅币
15934 个
贡献
30898 次
宅之契约
0 份
在线时间
1514 小时
注册时间
2014-1-26
 楼主| 发表于 2017-8-9 09:29:53 | 显示全部楼层
美俪女神 发表于 2017-8-9 08:44
最常见的负优化:“我比编译器牛逼”系列。
很多人用ASM写性能密集型程序,结果最后发现,执行效率还不如用 ...

自己写汇编除非写SIMD,不然基本都是负优化。有很多特性不是所有写汇编的人都知道的,比如不相干指令能同时执行的特性,有时候我说出去都没人信。

本版积分规则

QQ|申请友链|Archiver|手机版|小黑屋|技术宅的结界 ( 滇ICP备16008837号|网站地图

GMT+8, 2018-5-24 04:14 , Processed in 0.078246 second(s), 15 queries , Gzip On, Memcache On.

Powered by Discuz! X3.2

© 2001-2013 Comsenz Inc.

快速回复 返回顶部 返回列表