gpt4 book ai didi

c++ - 用于比较 (_mm_cmpeq_ps) 和赋值操作的 SSE 内在函数

转载 作者:行者123 更新时间:2023-11-30 01:28:06 25 4
gpt4 key购买 nike

我已经开始使用 SSE 优化我的代码。本质上,它是一种光线追踪器,通过将坐标存储在 __m128 数据类型 x、y、z 中(四条光线的坐标按轴分组),一次处理 4 条光线。但是我有一个分支语句可以防止被零除我似乎无法转换为 SSE。在系列中这是:

const float d = wZ == -1.0f ? 1.0f/( 1.0f-wZ) : 1.0f/(1.0f+wZ);

其中 wZ 是 z 坐标,需要对所有四条光线进行此计算。

我如何将其转化为 SSE?

我一直在尝试使用 SSE 等式比较,如下所示(现在 wz 属于 __m128 数据类型,其中包含四条射线中每条射线的 z 值):

_mm_cmpeq_ps(_mm_set1_ps(-1.0f) , wZ )

然后使用它来识别 wZ[x] = -1.0 的情况,取这种情况的绝对值,然后继续正常计算。

然而,我在这方面的努力并没有取得太大的成功。

最佳答案

这是一个相当简单的解决方案,它只使用 SSE 实现标量代码,而无需任何进一步优化。它可能会变得更有效率一点,例如通过利用当 wZ = -1.0 时结果将为 0.5 的事实,或者甚至可以不顾一切地进行除法,然后在事后将 INF 转换为 0.5。

我为 SSE4 和 pre-SSE4 使用了 #ifdefd,因为 SSE4 有一个“混合”指令,它可能比三个 pre-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;
}

关于c++ - 用于比较 (_mm_cmpeq_ps) 和赋值操作的 SSE 内在函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8004718/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com