SALVIA 0.5.2优化谈(二)

2014-11-24 08:08:50 · 作者: · 浏览: 1
优化后,性能没什么变化。当然,这也是意料之中的事情了。
因此,第二轮优化便着重考虑在插值算法本身上。
在优化之前,我尝试对代码成本做个粗略的评估:
在现有算法下,假设每个像素有N个需要插值的属性,则平均每个像素有
(corner)3N/16个读 + 2N/16个乘法 + 2N/16个加法 + N/16个写
(x:+=)2N个读 + N个加法 + N个写
(x:*) N个读 + 1个标量除法 + N个乘法 + N个写
(y:+=)2N/4个读 + N/4个加法 + N/4个写
(y:=) N/4个读 + N/4个写
因为每个都是函数指针,所以这些都是优化不掉的。因此首先将一些操作合并了一下,比如把+= 和*合并以减少一下读写操作。只可惜效果也不是很明显。
第二刀就砍到算法的头上。因为累加本身是为了减少乘法的运用,但是这可能带来了多余的存取开销。
因此直接套用公式:
pixel = ( projected_v0 + projected_ddx * offset_x + projected_ddy * offset_y ) / pixel_w
这样就有:3N读,2N乘法,2N加法,N个乘法和N个写(假设寄存器够用的话)。不算Corner的计算成本,这样比较一下,就等于是3N/4个读,N/2+N个写,N/4个加法来换取2N个乘法的时间。本来以为作为IO瓶颈的应用,这样可以提高一些性能。不过结果证实这个买卖实在是很不划算,整体性能不增反减。
三轮优化:减少内存占用,柳暗花明
虽然所有的操作只针对已使用的属性,但是空间上还是浪费了许多。
考虑到内存占用较大也会导致一些性能损失,于是将MAX_ATTRIBUTE_COUNT从32下调到了8。
结果令人大跌眼镜。性能瞬间提升了20-30%之多。
再加上SSE也不知道为什么开始发力了,使用上之后性能大约又有了10-15%的提升。
我猜测可能是因为换页频率下降,以及Cache的命中率提升。不过手上没有VTune这种工具,所以也不太好验证。
四轮优化:精度敏感性下降的额外红利
在这轮优化之后,PartOfSponza出现了精度问题。因为视锥体的上下左右四个面都没有Clip,所以可能会出现非常大的三角形。这样累积的时候一旦起始点选择的不好,就会出现比较大的误差。在之前版本中,使用/fp: precise来减少这一问题出现的机会。但是因为使用了SSE,也让这个问题再难解决。因此我选用了一些办法,来改善精度问题。在大问题都修正以后,换用/fp: fast来编译整个SALVIA,最终也获得了0-10%左右的性能收益。