simd相关内容

SSE向量化与内存对齐的关系

为什么我们需要 SSE/AVX 的对齐内存? 我经常得到的答案之一是对齐的内存加载比未对齐的内存加载快得多.那么,为什么这种对齐的内存加载比未对齐的内存加载快得多? 解决方案 这不仅特定于 SSE(甚至 x86).在大多数架构上,加载和存储需要自然对齐,否则它们要么 (a) 生成异常,要么 (b) 需要两个或更多周期加上一些修复,以便透明地处理未对齐的加载/存储.在 x86 (b) ..
发布时间:2021-08-27 19:45:15 其他开发

如何用SSE3实现符号功能?

1) 有没有办法有效地实现签名功能 使用具有以下特征的 SSE3(无 SSE4)? 输入是一个浮点向量__m128. 输出也应该是 __m128 以 [-1.0f, 0.0f, 1.0f] 作为其值 我试过了,但没有用(虽然我认为应该这样做): inputVal = _mm_set_ps(-0.5, 0.5, 0.0, 3.0);comp1 = _mm_cmpgt_ps(_mm_s ..
发布时间:2021-08-27 19:45:12 其他开发

如何反转 __m128 类型变量?

我知道这应该是一个谷歌搜索问题,但我就是找不到答案. 假设我有一个__m128变量a,其内容为a[0],a[1]、a[2]、a[3].是否有单个函数可以将其反转为a[3]、a[2]、a[1], a[0]? 解决方案 使用 _mm_shuffle_ps().该指令已在 SSE 中可用,通过组合来自两个输入向量中的每一个的两个任意 32 位分量,可以在单个向量中收集 4 个 32 位分量 ..
发布时间:2021-08-27 19:45:09 C/C++开发

如何否定(更改符号)__m128 类型变量中的浮点元素?

是否有任何单个指令或函数可以反转 __m128 中每个浮点数的符号?即 a = r0:r1:r2:r3 ===>a = -r0:-r1:-r2:-r3? 我知道这可以通过 _mm_sub_ps(_mm_set1_ps(0.0),a) 来完成,但是因为 _mm_set1_ps(0.0) 是一个多指令功能? 解决方案 在实践中,您的编译器应该很好地生成 0.0.0 的常量向量.它可能只会 ..
发布时间:2021-08-27 19:45:06 其他开发

SSE 乘法 16 x uint8_t

我想用 SSE4 乘以具有 16 个无符号 8 位整数的 __m128i 对象,但我只能找到一个用于乘以 16 位整数的内在函数.有没有_mm_mult_epi8之类的东西? 解决方案 MMX/SSE/AVX 中没有 8 位乘法.但是,您可以使用 16 位乘法来模拟 8 位乘法内在函数,如下所示: 内联 __m128i _mm_mullo_epi8(__m128i a, __m128i ..
发布时间:2021-08-27 19:45:01 其他开发

如何将两个 __m128 值组合为 __m256?

我想将两个 __m128 值合并为一个 __m256. 像这样: __m128 a = _mm_set_ps(1, 2, 3, 4);__m128 b = _mm_set_ps(5, 6, 7, 8); 类似于: __m256 c = { 1, 2, 3, 4, 5, 6, 7, 8 }; 是否有任何内在函数可用于执行此操作? 解决方案 这应该可以满足您的需求: __m12 ..
发布时间:2021-08-27 19:44:59 其他开发

SSE 比较返回 NAN 的向量

我正在尝试这样的事情: __m128 cA = _mm_set_ps1(-2.0f);__m128 cB = _mm_set_ps1(2.0f);__m128 df = _mm_cmpgt_ps(cA, cB); 在这种情况下 df 返回零. 但如果我这样做: __m128 cA = _mm_set_ps1(2.0f);__m128 cB = _mm_set_ps1(-2.0f);__ ..
发布时间:2021-08-27 19:44:56 其他开发

使用 SSE 时性能变差(整数数组的简单加法)

我正在尝试使用 SSE 内在函数来添加两个 32 位有符号整数数组.但与线性加法相比,我的性能非常差. 平台 - Intel Core i3 550、GCC 4.4.3、Ubuntu 10.04(有点旧,是的) #define ITER 1000typedef union sint4_u {__m128i v;sint32_t x[4];} sint4; 功能: void 计算(sin ..
发布时间:2021-08-27 19:44:53 其他开发

使用 SSE 对数,还是切换到 FPU?

我正在做一些统计计算.我需要它们很快,所以我重写了大部分以使用 SSE.我对它很陌生,所以我想知道这里的正确方法是什么: 据我所知,SSE 中没有 log2 或 ln 函数,至少没有达到 4.1,这是我使用的硬件支持的最新版本. 是否更好: 提取 4 个浮点数,并对它们进行 FPU 计算以确定熵 - 我不需要将这些值中的任何一个加载回 SSE 寄存器,只需将它们与另一个浮点数相加 ..
发布时间:2021-08-27 19:44:50 其他开发

SSE:_mm_load/store 与使用直接指针访问的区别

假设我要添加两个缓冲区并存储结果.两个缓冲区都已分配为 16 字节对齐.我找到了两个如何做到这一点的例子. 第一个是使用 _mm_load 将数据从缓冲区读取到 SSE 寄存器中,执行加法操作并存储回结果寄存器.直到现在我都会这样做. void _add( uint16_t * dst, uint16_t const * src, size_t n ){for( uint16_t cons ..
发布时间:2021-08-27 19:44:44 其他开发

如何比较 __m128 类型?

__m128 a;__m128 b; 如何编码a != b ? 使用什么:_mm_cmpneq_ps 或 _mm_cmpneq_ss ? 如何处理结果? 找不到足够的文档. 解决方案 您可能应该使用 _mm_cmpneq_ps.但是,SIMD 代码与标量代码的比较解释略有不同.你想测试 any 对应的元素不相等吗?还是所有对应的元素不相等? 要测试 _mm_cmp ..
发布时间:2021-08-27 19:44:41 其他开发

将分散索引转换为聚集索引的有效方法?

我正在尝试使用 SIMD 内在函数编写流压缩(采用数组并去除空元素).循环的每次迭代一次处理 8 个元素(SIMD 宽度). 使用 SSE 内在函数,我可以使用 _mm_shuffle_epi8() 相当有效地执行此操作,它执行 16 个条目表查找(收集并行计算术语).shuffle 索引是预先计算好的,并使用位掩码查找. for (i = 0; i 我的问题是现在我也想为 Altiv ..
发布时间:2021-08-27 19:44:36 其他开发

英特尔 SSE:为什么 `_mm_extract_ps` 返回 `int` 而不是 `float`?

为什么 _mm_extract_ps 返回的是 int 而不是 float? 从 C 中的 XMM 寄存器读取单个 float 的正确方法是什么? 或者更确切地说,一种不同的提问方式是:_mm_set_ps 指令的反面是什么? 解决方案 来自 MSDN 文档,我相信您可以将结果转换为浮点数. 注意他们的例子,0xc0a40000 值等价于 -5.125 (a.m128_f ..
发布时间:2021-08-27 19:44:33 其他开发

如何使用 SSE 执行 uint32/float 转换?

在 SSE 中有一个函数 _mm_cvtepi32_ps(__m128i input) 它接受 32 位宽有符号整数 (int32_t) 的输入向量并将它们转换为 floats. 现在,我想将输入整数解释为未签名.但是没有函数 _mm_cvtepu32_ps 并且我找不到一个实现.你知道我在哪里可以找到这样的函数或者至少给出一个实现的提示吗?为了说明结果的差异: unsigned int ..
发布时间:2021-08-27 19:44:30 其他开发

测试两个 __m128i 变量之间的相等性

如果我想在两个 __m128i 变量之间进行按位相等测试,我需要使用 SSE 指令还是可以使用 ==?如果不是,我应该使用哪个 SSE 指令? 解决方案 虽然使用 _mm_movemask_epi8 是一种解决方案,但如果您的处理器采用 SSE4.1 我认为更好的解决方案是使用指令它在 FLAGS 寄存器中设置零或进位标志.这可以节省test 或 cmp 指令. 要做到这一点,你可以 ..
发布时间:2021-08-27 19:44:27 其他开发

SSE:将短整数转换为浮点数

我想使用 SSE 将一组无符号短数转换为浮点数.说吧 __m128i xVal;//有 8 个 16 位无符号整数__m128 y1, y2;//2 个 xmm 寄存器,用于 8 个浮点值 我想要 y1 中的前 4 个 uint16 &y2 中的下一个 4 uint16.需要知道使用哪个 sse 内在的. 解决方案 您需要先将 8 x 16 位无符号短整型向量解包为两个 32 位无符号 ..
发布时间:2021-08-27 19:44:24 其他开发

使用AVX2收集指令时的加载地址计算

查看 AVX2 内部函数文档,那里收集了一些加载指令,例如 VPGATHERDD: __m128i _mm_i32gather_epi32 (int const * base, __m128i index, const int scale); 我从文档中不清楚计算出的加载地址是元素地址还是字节地址,即元素i: load_addr = base + index[i] * scale;//(1) ..
发布时间:2021-08-27 19:44:20 其他开发

使用 SSE 计算绝对值的最快方法

我知道有 3 种方法,但据我所知,一般只使用前 2 种: 使用 andps 或 andnotps 屏蔽符号位. 优点:如果掩码已在寄存器中,则是一条快速指令,非常适合在循环中多次执行此操作. 缺点:掩码可能不在寄存器中或更糟,甚至不在缓存中,从而导致非常长的内存提取. 将值从零减去求反,然后得到原值的最大值并求反. 优点:固定成本,因为不需要获取任何东西,例如面具. 缺 ..
发布时间:2021-08-27 19:44:17 其他开发

SIMD 代码在 Debug 中有效,但在 Release 中无效

此代码在调试模式下工作,但由于发布模式下的断言而导致恐慌. 使用 std::arch::x86_64::*;fn 主(){不安全{让 a = vec![2.0f32, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0];让 b = -1.0f32;让 ar = _mm256_loadu_ps(a.as_ptr());println!("ar: {:?}", ar);让 br = ..
发布时间:2021-07-13 20:56:39 其他开发