[Bf-blender-cvs] [81c9e0d] master: Cycles: Avoid branching in SSE version of intersection pre-calculation

Sergey Sharybin noreply at git.blender.org
Tue Oct 25 15:34:28 CEST 2016


Commit: 81c9e0d2958a1274f8cb76386a3bafc08a181eed
Author: Sergey Sharybin
Date:   Tue Oct 25 14:18:32 2016 +0200
Branches: master
https://developer.blender.org/rB81c9e0d2958a1274f8cb76386a3bafc08a181eed

Cycles: Avoid branching in SSE version of intersection pre-calculation

Similar to the previous commit, avoid negative effect of bad branch prediction.

Gives measurable performance up to ~2% in tests here.

Once again, thanks to Maxym Dmytrychenko!

===================================================================

M	intern/cycles/kernel/geom/geom_triangle_intersect.h

===================================================================

diff --git a/intern/cycles/kernel/geom/geom_triangle_intersect.h b/intern/cycles/kernel/geom/geom_triangle_intersect.h
index 8d17e12..5d76fc3 100644
--- a/intern/cycles/kernel/geom/geom_triangle_intersect.h
+++ b/intern/cycles/kernel/geom/geom_triangle_intersect.h
@@ -59,21 +59,33 @@ void triangle_intersect_precalc(float3 dir,
                                 IsectPrecalc *isect_precalc)
 {
 	/* Calculate dimension where the ray direction is maximal. */
+#ifndef __KERNEL_SSE__
 	int kz = util_max_axis(make_float3(fabsf(dir.x),
 	                                   fabsf(dir.y),
 	                                   fabsf(dir.z)));
 	int kx = kz + 1; if(kx == 3) kx = 0;
 	int ky = kx + 1; if(ky == 3) ky = 0;
+#else
+	int kx, ky, kz;
+	/* Avoiding mispredicted branch on direction. */
+	kz = util_max_axis(fabs(dir));
+	static const char inc_xaxis[] = {1, 2, 0, 55};
+	static const char inc_yaxis[] = {2, 0, 1, 55};
+	kx = inc_xaxis[kz];
+	ky = inc_yaxis[kz];
+#endif
+
+	float dir_kz = IDX(dir, kz);
 
 	/* Swap kx and ky dimensions to preserve winding direction of triangles. */
-	if(IDX(dir, kz) < 0.0f) {
+	if(dir_kz < 0.0f) {
 		int tmp = kx;
 		kx = ky;
 		ky = tmp;
 	}
 
 	/* Calculate the shear constants. */
-	float inv_dir_z = 1.0f / IDX(dir, kz);
+	float inv_dir_z = 1.0f / dir_kz;
 	isect_precalc->Sx = IDX(dir, kx) * inv_dir_z;
 	isect_precalc->Sy = IDX(dir, ky) * inv_dir_z;
 	isect_precalc->Sz = inv_dir_z;




More information about the Bf-blender-cvs mailing list