纳金网

标题: 为何纹理导入的速度如此之慢?让我们一探究竟(上) [打印本页]

作者: tianhett    时间: 2015-2-25 10:38
标题: 为何纹理导入的速度如此之慢?让我们一探究竟(上)



我曾看到过一份奇怪的错误报告:“纹理导入在当前beta版本中要慢得多”。刚开始,我对它并不重视。当我迅速尝试了几个纹理后,并发觉并没有什么异样。我感叹道,“哦,或许这只是个别人的困惑吧”。但之后,我得到了关于多纹理的一份合适的bug报告。其中它的一个导入过程要比平常的导入大约慢上10倍。
为什么有些人会让纹理导入过程慢很多呢?当然,没有人会这么做。原来,它只是一个意想不到的改观后的结果。
看到错误报告后,起初我想使用xperf(又称Windows性能工具包)。信不信由你,我从前没有使用过xperf。
这是我们的故事
我们得到一个TGA纹理(一个2048×2048,未压缩的12MB大小的文件),它要花10秒钟输入到当前的beta数据中,但它在unity 4.6版本中仅用1秒就能完成。
首个大胆猜想:有没有人会意外地停止使用多线程的纹理压缩吗?我感觉不大可能,看起来不像(这是因为在完成最终的纹理压缩过程中仍显示出大量的恢复)。
第二个猜想:目前,我们正使用FreeImage库来引进纹理。我不清楚有没有人会更新它,并把它做出一个调试版本吗?好像没有人做。最后一次更改我们构建的工作还是几个月前完成的。
花时间去配置文件。我在Windows的分析器上迅速打出“我需要在5秒钟之内得到回答”,然后就休眠了(Very Sleepy)。让我们来看看下表:


要等待什么?把所有时间都花费在WinAPI ReadFile的函数中吗?
我需要测试特别的TGA文件吗?让我们做出同样大小,未压缩的PNG图像(因此,文件大小是一样的)。


108ms(毫秒)内完成PNG导入,而TGA需要9800ms内完成(我已经关闭了DXT压缩,只关注导入时间)。在Unity 4.6中,完成同样的工作,PNG花费116ms,TGA花费310ms。要注意文件大小基本相同。
输入xperf
当我问一同事谁知道Windows时,他回答到,“为什么要花费所有时间在ReadFile中读取文件呢?但同样大小的另一个文件读取更为迅速。来看看xperf吧。”
我在布鲁斯•道森的精彩博客中阅读过xperf的文章,但我从未尝试过。我在今天要试一把。
因此,我们就发布个Windows性能记录器(我甚至不知道它有VS版本和SDK版本,还需要单独安装……),在CPU,磁盘或文件或I/O上发出滴答声,并点击开始:


在Unity中完成纹理导入,点击保存,这一步骤有些令人费解,在屏幕上点击“在WPA中打开”:


侧边栏的综述中给出了图形的使用情况。有一个奇怪的事情:CPU(计算)和存储图形都没有显示出高强度活动吗?事情变得复杂了!


CPU使用情况调查
双击点击计算图表时,在时间轴中显示出了CPU的使用情况和每个过程中的图表。我们可以看到Unity.exe程序占用CPU的情况,其中UI非常突出。


下一件事是我们想要知道还有什么内容正占用着CPU。在黄色分频器左侧列表中的UI组显示出了右侧的详细情况。目前,我们对callstack感兴趣,我们就在分频器左边点击context,并选择“Stack”:


没错,要得到任何使用着的堆栈(stack),我们就要告知xperf去加载符号。你要做的操作是Trace -> Configure Symbol Paths,添加Unity文件夹,并Trace -> Load Symbols。
然后你将进入等待。有更多新内容将出现…
然后你得到callstacks!不太清楚什么是“n/a”入口;我最好的一个猜测就是它代表未使用的CPU核或者是休眠线程之类的东西。
当进入到其他调用堆栈后,我们确实看到所有时间都花费在ReadFile中了。


那么,这不是非常实用;我们已从Very Sleepy性能分析中得出此种结论。







欢迎光临 纳金网 (http://go.narkii.com/club/) Powered by Discuz! X2.5