修改的SSE版本

SSE version of modf

本文关键字:版本 SSE 修改      更新时间:2023-10-16

我有以下使用 SSE 内部函数的 modf 工作实现,但是当我需要将结果作为__m128时,在此过程中转换为 __m128i 并返回似乎很浪费。

__m128 integer = _mm_cvtepi32_ps(_mm_cvttps_epi32(value));
__m128 fraction = _mm_sub_ps(value, integer);

是否存在没有类型转换或一些幻数破解的截断指令?

在 SSE4.1 中,您可以使用roundpsroundpd说明:

//  Single Precision
__m128 integer = _mm_round_ps(value,_MM_FROUND_TRUNC);
__m128 fraction = _mm_sub_ps(value,integer);
//  Double Precision
__m128d integer = _mm_round_pd(value,_MM_FROUND_TRUNC);
__m128d fraction = _mm_sub_pd(value,integer);

这将分隔整数和小数部分,同时保留两者的符号。

同样,对于 AVX:

//  Single Precision
__m256 integer = _mm256_round_ps(value,_MM_FROUND_TRUNC);
__m256 fraction = _mm256_sub_ps(value,integer);
//  Double Precision
__m256d integer = _mm256_round_pd(value,_MM_FROUND_TRUNC);
__m256d fraction = _mm256_sub_pd(value,integer);

如果您也有 XOP 指令集,则只需一条指令(通过_mm256_frcz_pd和系列(即可单独获得小数部分。

但是如果没有SSE4.1,那么除了转换或执行+/-魔术之外,没有更好的方法可以做到这一点。(在溢出的情况下,两者都会遇到问题(