這是一個相當直接的解決方案,它只是用SSE實現標量代碼而不需要進一步優化。它可能會更有效率,例如通過利用當wZ = -1.0時結果爲0.5的事實,或者甚至可以通過僅僅進行除法,然後在事實之後將INF
s轉換爲0.5來實現。
對於SSE4與pre-SSE4,我已經有#ifdef
d了,因爲SSE4有一個「混合」指令,這個指令可能更有效一些屏蔽和選擇值所需的三個預先SSE4指令。
#include <emmintrin.h>
#ifdef __SSE4_1__
#include <smmintrin.h>
#endif
#include <stdio.h>
int main(void)
{
const __m128 vk1 = _mm_set1_ps(1.0f); // useful constants
const __m128 vk0 = _mm_set1_ps(0.0f);
__m128 wZ, d, d0, d1, vcmp;
#ifndef __SSE4_1__ // pre-SSE4 implementation
__m128 d0_masked, d1_masked;
#endif
wZ = _mm_set_ps(-1.0f, 0.0f, 1.0f, 2.0f); // test inputs
d0 = _mm_add_ps(vk1, wZ); // d0 = 1.0 - wZ
d1 = _mm_sub_ps(vk1, wZ); // d1 = 1.0 + wZ
vcmp = _mm_cmpneq_ps(d1, vk0); // test for d1 != 0.0, i.e. wZ != -1.0
#ifdef __SSE4_1__ // SSE4 implementation
d = _mm_blendv_ps(d0, d1, vcmp);
#else // pre-SSE4 implementation
d0_masked = _mm_andnot_ps(vcmp, d0);
d1_masked = _mm_and_ps(vcmp, d1);
d = _mm_or_ps(d0_masked, d1_masked); // d = wZ == -1.0 ? 1.0/(1.0 - wZ) : 1.0/(1.0 + wZ)
#endif
d = _mm_div_ps(vk1, d);
printf("wZ = %vf\n", wZ);
printf("d = %vf\n", d);
return 0;
}
除以零有什麼問題? – Pubby
除了明顯的問題之外,它還會通過在算法的其餘部分爲Nz = -1創建不一致性來破壞結果。 – cubiclewar