AVX 将 64 位整数转换为 64 位浮点数

Posted

技术标签:

【中文标题】AVX 将 64 位整数转换为 64 位浮点数【英文标题】:AVX convert 64 bit integer to 64 bit float 【发布时间】:2013-05-12 23:17:14 【问题描述】:

我想使用 AVX 将 4 个压缩的 64 位整数转换为 4 个压缩的 64 位浮点数。我尝试过类似的方法:

int_64t *ls = (int64_t *) _mm_malloc(256, 32);
ls[0] = a;
//...
ls[3] = d;

__mm256i packed = _mm256_load_si256((__m256i const *)ls);

将在调试器中显示:

(gdb) print packed
$4 = 1234, 5678, 9012, 3456

到目前为止还可以,但我能找到的唯一转换/转换操作是 _mm256i_castsi256_pd,它没有得到我想要的:

__m256d pd = _mm256_castsi256_pd(packed);

(gdb) print pd
$5 = 6.0967700696809824e-321, 2.8053047370865979e-320, 4.4525196003213139e-320, 1.7074908720273481e-320

我真正想看到的是:

(gdb) print pd
$5 = 1234.0, 5678.0, 9012.0, 3456.0

【问题讨论】:

另见:Best way to load a 64-bit integer to a double precision SSE2 register?。请注意,如果您不想对压缩双精度向量中的位做出假设(或使用丑陋的技巧来修改),您始终可以执行两个CVTDQ2PD,一次使用低 32 位,然后再次使用高位32位,最后将packed-double向量相加。 【参考方案1】:

所有 cast 内在函数都执行按位强制转换,这就是为什么您看不到有意义的结果的原因。

不存在 64 位整数和 64 位浮点之间的向量转换(cvt 内在函数)。

【讨论】:

我猜是这样,为确认欢呼。是时候以不同的方式解决问题了。 另外,请注意不能用 64 位整数和 64 位浮点数表示相同的数字。每种格式的大多数数字在另一种格式中没有等价物。 64 位浮点数比 int 大/小得多,因此您甚至无法尝试。从 int 到 float 尽可能最好的方式(不是按位转换),你会得到近似值,但不要对它们做任何重要的事情。【参考方案2】:

对于它的价值,我查看了 Agner Fog 的矢量类,看看他是如何做到的。他只是将 64 位整数存储到一个数组中,并将每个数组值转换为一个双精度值。它效率低下,但很有效。

来自文件“vectorf256.h”:

// function to_double: convert integer vector elements to double vector (inefficient)
static inline Vec4d to_double(Vec4q const & a) 
    int64_t aa[4];
    a.store(aa);
    return Vec4d(double(aa[0]), double(aa[1]), double(aa[2]), double(aa[3]));


// function to_double: convert integer vector to double vector
static inline Vec4d to_double(Vec4i const & a) 
    return _mm256_cvtepi32_pd(a);

【讨论】:

以上是关于AVX 将 64 位整数转换为 64 位浮点数的主要内容,如果未能解决你的问题,请参考以下文章

浮点数的十六进制表示

将十进制数表示成ieee754标准的32浮点规格化数 27/64

将 32 位浮点数转换为 16 位 PCM 范围

转置 8x8 64 位矩阵

使用 AVX512 将压缩 64 位整数转换为带符号饱和的压缩 8 位整数

如何在 x86(32 位)程序集中将无符号整数转换为浮点数?