Floating point lrintf的AVX2等效值

Floating point lrintf的AVX2等效值,floating-point,rounding,avx,avx2,Floating Point,Rounding,Avx,Avx2,我目前有一个简单的C循环,它使用lrintf将数组从浮点转换为int, 使用默认舍入策略。我想把它放到我的AVX2例程中-是否有一个与使用SIMD的lrintf等效的命令? 顺便说一句,在lrintf之后,我将结果钳制为用户指定的最小值和最大值 谢谢 而lrintf()的原型是long-int-lrintf(float),OP在评论中澄清,他们正在寻找从float到32位int的转换 AVX内部版本非常适合这种情况:它使用当前舍入模式提供从float到32位int的转换,即使对于我熟悉的所有软件

我目前有一个简单的C循环,它使用
lrintf
将数组从浮点转换为int, 使用默认舍入策略。我想把它放到我的AVX2例程中-是否有一个与使用SIMD的
lrintf
等效的命令? 顺便说一句,在
lrintf
之后,我将结果钳制为用户指定的最小值和最大值


谢谢

lrintf()
的原型是
long-int-lrintf(float),OP在评论中澄清,他们正在寻找从
float
到32位
int
的转换

AVX内部版本非常适合这种情况:它使用当前舍入模式提供从
float
到32位
int
的转换,即使对于我熟悉的所有软件环境,该模式默认为舍入到最近

以下小测试程序的输出应如下所示:

source vector:  1.000000  1.100000  1.500000  1.900000 -1.000000 -1.100000 -1.500000 -1.900000
round to nearest:   1  1  2  2 -1 -1 -2 -2
round down:         1  1  1  1 -1 -2 -2 -2
round up:           1  2  2  2 -1 -1 -1 -1
round toward zero:  1  1  1  1 -1 -1 -1 -1
但是,我注意到,选择
-O0
以上的任何优化级别都会给我的旧版英特尔编译器带来不正确的结果,这可能是因为编译器会移动
\umm\u SET\u ROUNDING\u MODE()
实例,而不考虑这些实例与周围计算之间的隐式依赖关系。我不知道该怎么办。我已经使用最严格的浮点设置进行编译,还尝试在
上添加
#include
,然后添加
#pragma STDC FENV_ACCESS,但没有成功

#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <string.h>
#include <math.h>
#include "immintrin.h"

int main (void)
{
    __m256 float_vec;
    __m256i int_vec_rn;
    __m256i int_vec_rd;
    __m256i int_vec_ru;
    __m256i int_vec_rz;
    float arg[8] = {1.0f, 1.1f, 1.5f, 1.9f, -1.0f, -1.1f, -1.5f, -1.9f};
    int32_t res[8];

    unsigned int old_rm = _MM_GET_ROUNDING_MODE();
    printf ("source vector: % f % f % f % f % f % f % f % f\n",
            arg[0], arg[1], arg[2], arg[3], arg[4], arg[5], arg[6], arg[7]);
    memcpy (&float_vec, arg, sizeof float_vec);

    _MM_SET_ROUNDING_MODE (_MM_ROUND_NEAREST);
    int_vec_rn = _mm256_cvtps_epi32 (float_vec);
    memcpy (res, &int_vec_rn, sizeof res);
    printf ("round to nearest:  % d % d % d % d % d % d % d % d\n", 
            res[0], res[1], res[2], res[3], res[4], res[5], res[6], res[7]);

    _MM_SET_ROUNDING_MODE (_MM_ROUND_DOWN);
    int_vec_rd = _mm256_cvtps_epi32 (float_vec);
    memcpy (res, &int_vec_rd, sizeof res);
    printf ("round down:        % d % d % d % d % d % d % d % d\n", 
            res[0], res[1], res[2], res[3], res[4], res[5], res[6], res[7]);

    _MM_SET_ROUNDING_MODE (_MM_ROUND_UP);
    int_vec_ru = _mm256_cvtps_epi32 (float_vec);
    memcpy (res, &int_vec_ru, sizeof res);
    printf ("round up:          % d % d % d % d % d % d % d %d\n", 
            res[0], res[1], res[2], res[3], res[4], res[5], res[6], res[7]);

    _MM_SET_ROUNDING_MODE (_MM_ROUND_TOWARD_ZERO);
    int_vec_rz = _mm256_cvtps_epi32 (float_vec);
    memcpy (res, &int_vec_rz, sizeof res);
    printf ("round toward zero: % d % d % d % d % d % d % d % d\n", 
            res[0], res[1], res[2], res[3], res[4], res[5], res[6], res[7]);

    _MM_SET_ROUNDING_MODE (old_rm);
    return EXIT_SUCCESS;
}
#包括
#包括
#包括
#包括
#包括
#包括“immintrin.h”
内部主(空)
{
__m256浮点数;
__m256i国际车辆;
__m256i国际车辆路;
__m256i国际汽车集团;
__m256i国际车辆中心;
浮点数arg[8]={1.0f、1.1f、1.5f、1.9f、-1.0f、-1.1f、-1.5f、-1.9f};
int32_t res[8];
unsigned int old_rm=_MM_GET_ROUNDING_MODE();
printf(“源向量:%f%f%f%f%f%f%f%f\n”,
arg[0]、arg[1]、arg[2]、arg[3]、arg[4]、arg[5]、arg[6]、arg[7];
memcpy(&float_vec,arg,float_vec的大小);
_MM_设置_取整_模式(_MM_取整_最近);
int_vec_rn=_mm256_cvtps_epi32(浮动向量);
memcpy(res和intvec、sizeof res);
printf(“四舍五入到最近的:%d%d%d%d%d%d%d%d\n”,
res[0]、res[1]、res[2]、res[3]、res[4]、res[5]、res[6]、res[7];
_MM_设置_取整模式(_MM_取整模式下);
int_vec_rd=_mm256_cvtps_epi32(浮动向量);
memcpy(res和int_vec_路,res尺寸);
printf(“向下取整:%d%d%d%d%d%d%d%d%d\n”,
res[0]、res[1]、res[2]、res[3]、res[4]、res[5]、res[6]、res[7];
_MM_设置_取整模式(_MM_取整模式);
int_vec_ru=_mm256_cvtps_epi32(浮动向量);
memcpy(res和int_vec_ru、sizeof res);
printf(“汇总:%d%d%d%d%d%d%d%d%d\n”,
res[0]、res[1]、res[2]、res[3]、res[4]、res[5]、res[6]、res[7];
_MM_设置_取整_模式(_MM_取整_朝向_零);
int_vec_rz=_mm256_cvtps_epi32(浮点向量);
memcpy(res和int_vec_rz,res的大小);
printf(“向零舍入:%d%d%d%d%d%d%d%d%d\n”,
res[0]、res[1]、res[2]、res[3]、res[4]、res[5]、res[6]、res[7];
_MM_设置_取整_模式(旧_rm);
返回退出成功;
}

lrintf()的原型是
long int lrintf(float),OP在评论中澄清,他们正在寻找从
float
到32位
int
的转换

AVX内部版本非常适合这种情况:它使用当前舍入模式提供从
float
到32位
int
的转换,即使对于我熟悉的所有软件环境,该模式默认为舍入到最近

以下小测试程序的输出应如下所示:

source vector:  1.000000  1.100000  1.500000  1.900000 -1.000000 -1.100000 -1.500000 -1.900000
round to nearest:   1  1  2  2 -1 -1 -2 -2
round down:         1  1  1  1 -1 -2 -2 -2
round up:           1  2  2  2 -1 -1 -1 -1
round toward zero:  1  1  1  1 -1 -1 -1 -1
但是,我注意到,选择
-O0
以上的任何优化级别都会给我的旧版英特尔编译器带来不正确的结果,这可能是因为编译器会移动
\umm\u SET\u ROUNDING\u MODE()
实例,而不考虑这些实例与周围计算之间的隐式依赖关系。我不知道该怎么办。我已经使用最严格的浮点设置进行编译,还尝试在
上添加
#include
,然后添加
#pragma STDC FENV_ACCESS,但没有成功

#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <string.h>
#include <math.h>
#include "immintrin.h"

int main (void)
{
    __m256 float_vec;
    __m256i int_vec_rn;
    __m256i int_vec_rd;
    __m256i int_vec_ru;
    __m256i int_vec_rz;
    float arg[8] = {1.0f, 1.1f, 1.5f, 1.9f, -1.0f, -1.1f, -1.5f, -1.9f};
    int32_t res[8];

    unsigned int old_rm = _MM_GET_ROUNDING_MODE();
    printf ("source vector: % f % f % f % f % f % f % f % f\n",
            arg[0], arg[1], arg[2], arg[3], arg[4], arg[5], arg[6], arg[7]);
    memcpy (&float_vec, arg, sizeof float_vec);

    _MM_SET_ROUNDING_MODE (_MM_ROUND_NEAREST);
    int_vec_rn = _mm256_cvtps_epi32 (float_vec);
    memcpy (res, &int_vec_rn, sizeof res);
    printf ("round to nearest:  % d % d % d % d % d % d % d % d\n", 
            res[0], res[1], res[2], res[3], res[4], res[5], res[6], res[7]);

    _MM_SET_ROUNDING_MODE (_MM_ROUND_DOWN);
    int_vec_rd = _mm256_cvtps_epi32 (float_vec);
    memcpy (res, &int_vec_rd, sizeof res);
    printf ("round down:        % d % d % d % d % d % d % d % d\n", 
            res[0], res[1], res[2], res[3], res[4], res[5], res[6], res[7]);

    _MM_SET_ROUNDING_MODE (_MM_ROUND_UP);
    int_vec_ru = _mm256_cvtps_epi32 (float_vec);
    memcpy (res, &int_vec_ru, sizeof res);
    printf ("round up:          % d % d % d % d % d % d % d %d\n", 
            res[0], res[1], res[2], res[3], res[4], res[5], res[6], res[7]);

    _MM_SET_ROUNDING_MODE (_MM_ROUND_TOWARD_ZERO);
    int_vec_rz = _mm256_cvtps_epi32 (float_vec);
    memcpy (res, &int_vec_rz, sizeof res);
    printf ("round toward zero: % d % d % d % d % d % d % d % d\n", 
            res[0], res[1], res[2], res[3], res[4], res[5], res[6], res[7]);

    _MM_SET_ROUNDING_MODE (old_rm);
    return EXIT_SUCCESS;
}
#包括
#包括
#包括
#包括
#包括
#包括“immintrin.h”
内部主(空)
{
__m256浮点数;
__m256i国际车辆;
__m256i国际车辆路;
__m256i国际汽车集团;
__m256i国际车辆中心;
浮点数arg[8]={1.0f、1.1f、1.5f、1.9f、-1.0f、-1.1f、-1.5f、-1.9f};
int32_t res[8];
unsigned int old_rm=_MM_GET_ROUNDING_MODE();
printf(“源向量:%f%f%f%f%f%f%f%f\n”,
arg[0]、arg[1]、arg[2]、arg[3]、arg[4]、arg[5]、arg[6]、arg[7];
memcpy(&float_vec,arg,float_vec的大小);
_MM_设置_取整_模式(_MM_取整_最近);
int_vec_rn=_mm256_cvtps_epi32(浮动向量);
memcpy(res和intvec、sizeof res);
printf(“四舍五入到最近的:%d%d%d%d%d%d%d%d\n”,
res[0]、res[1]、res[2]、res[3]、res[4]、res[5]、res[6]、res[7];
_MM_设置_取整模式(_MM_取整模式下);
int_vec_rd=_mm256_cvtps_epi32(浮动向量);
memcpy(res和int_vec_路,res尺寸);
printf(“向下取整:%d%d%d%d%d%d%d%d%d\n”,
res[0]、res[1]、res[2]、res[3]、res[4]、res[5]、res[6]、res[7];
_MM_设置_取整模式(_MM_取整模式);
int_vec_ru=_mm256_cvtps_epi32(浮动向量);
memcpy(res和int_vec_ru、sizeof res);
printf(“汇总:%d%d%d%d%d%d%d%d%d\n”,
res[0]、res[1]、res[2]、res[3]、res[4]、res[5]、res[6]、res[7];
_MM_设置_取整_模式(_MM_取整_朝向_零);
int_vec_rz=_mm256_cvtps_epi32(浮点向量);
memcpy(res和int_vec_rz,res的大小);
printf(“向零舍入:%d%d%d%d%d%d%d%d%d\n”,
res[0]、res[1]、res[2]、res[3]、res[4]、res[5]、res[6]、res[7];
_MM_设置_取整_M