【发布时间】:2015-07-09 15:43:28
【问题描述】:
我在 SSE 上遇到了一个非常微妙的问题。就是这样,我想用 SSE 优化我的光线追踪器,这样我就可以基本了解如何使用 SSE 来提高性能。
我想从这个功能开始。
Vector3f Add( const Vector3f& v0 , Vector3f& v1 );
(实际上我是先尝试优化 CrossProduct,为了简单起见,这里显示了添加,我知道这不是我的光线追踪器的瓶颈。)
这里是结构体定义的一部分:
struct Vector3f
{ union { struct{ float x ; float y ; float z; float reserved; }; __m128 data; };
问题是 SSE 寄存器会随着这个声明而刷新,编译器不够聪明,无法保存这些 sse 寄存器以供进一步使用。 并且通过以下声明,它避免了冲洗。
__m128 Add( __m128 v0_data, __m128 v1_data );
我可以在这种情况下采用这种方式,但是对于包含四个 __m128 数据的 Matrix 来说,这将是丑陋的设计。而且您不能让运算符在 Vector3f 本身上工作,而是在其数据上工作,:(.
最令人不安的是,您必须在各处更改更高级别的代码以适应更改。而这种通过 SSE 进行优化的方式对于大型游戏引擎这样的大型项目绝对是不可取的,你会在它工作之前更改大量代码。
如果不避免SSE寄存器刷新,我猜它的功率将被那些无用的刷新命令耗尽,这使得SSE无用。
【问题讨论】:
-
@JerryCao1985 您可以通过编辑直接在问题中提及这一点,而不是将其添加为评论。
-
如果您认真对待 SIMD 优化,那么您需要准备好完全重构您的代码,以便您可以完全在 SIMD 中均匀地处理大块数据。正如您在上面的示例中已经看到的那样,尝试以特别的方式将 SIMD 应用于现有代码库通常是次优的。
-
IOW:你不能一边吃蛋糕一边吃。
-
它绝对是大型游戏引擎的一个选项,是的,SIMD 入侵并试图“污染”你的所有代码。随它吧。只需从一开始就牢记这一点来编写代码,就可以了。