问题标签 [sse]

For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.

0 投票
4 回答
27082 浏览

c - 如何使用 C 中的 SSE 内在函数计算单向量点积

我试图将两个向量相乘,其中一个向量的每个元素乘以另一个向量的相同索引中的元素。然后我想对结果向量的所有元素求和以获得一个数字。例如,向量 {1,2,3,4} 和 {5,6,7,8} 的计算如下所示:

本质上,我正在取两个向量的点积。我知道有一个 SSE 命令可以执行此操作,但该命令没有与之关联的内在函数。此时,我不想在我的 C 代码中编写内联汇编,所以我只想使用内部函数。这似乎是一个常见的计算,所以我对自己在谷歌上找不到答案感到惊讶。

注意:我正在针对支持 SSE 4.2 的特定微架构进行优化。

0 投票
4 回答
3203 浏览

c - 使用 SSE 内在函数将 4 个点积存储到 C 中的连续数组中的最有效方法

我正在使用 SSE 内在函数为 Intel x86 Nehalem 微架构优化一些代码。

我的程序的一部分计算 4 个点积,并将每个结果添加到数组的连续块中的先前值。进一步来说,

请注意,我将使用 4 个临时 xmm 寄存器来保存每个点积的结果。在每个 xmm 寄存器中,相对于其他临时 xmm 寄存器,结果被放入一个唯一的 32 位中,因此最终结果如下所示:

tmp0= R0-零-零-零

tmp1= 零-R1-零-零

tmp2= 零-零-R2-零

tmp3=零-零-零-R3

我将每个 tmp 变量中包含的值合并为一个 xmm 变量,方法是使用以下指令将它们相加:

最后,我将包含点积的所有 4 个结果的寄存器添加到数组的连续部分,以便数组的索引按点积递增,就像这样(C_0n 是数组中当前要更新的 4 个值; C_2 是指向这4个值的地址):

我想知道是否有一种不那么迂回、更有效的方法来获取点积的结果并将它们添加到数组的连续块中。这样,我在其中只有 1 个非零值的寄存器之间进行了 3 次加法。似乎应该有一种更有效的方法来解决这个问题。

我感谢所有帮助。谢谢你。

0 投票
1 回答
1962 浏览

c - SSE 移位整数

我试图了解如何使用 SSE 进行转换,但我不明白 gdb 给我的输出。使用 SSE4 我有一个 128 位向量,其中包含 8 个 16 位无符号整数(使用uint16_t)。然后我使用内在函数_mm_cmpgt_epi16将它们与某个值进行比较,该函数将所有 0 或 1 位放入用于存储整数的位中。到目前为止一切顺利,使用 gdb 我得到:

然后我想把它们移到右边(对吗?)所以我只得到一个数值 1 以防万一。然后 GDB 给了我一个我不明白的输出:

它甚至与第一个长度不一样,这是为什么呢?只是为了尝试一下,我使用以下内在函数将其向右移动一位:

我希望它在每个 16 位块的右端只移动一个零。

更新:

我写了一个小例子来测试使用位掩码的东西,它工作正常,但我仍然不明白 gdbs 的行为:


我的 gdb 版本:GNU gdb 6.3.50-20050815 (Apple version gdb-1472) (Wed Jul 21 10:53:12 UTC 2010)

编译器标志:-Wall -g -O0 -mssse3 -msse4 -std=c99

0 投票
2 回答
5257 浏览

c - 从 128 位 SSE 向量中加载和提取 32 位整数值的最有效方法是什么?

我正在尝试使用 SSE 内在函数优化我的代码,但遇到了一个问题,在我完成 SSE 内在函数操作以获得我想要的内容后,我不知道从向量中提取整数值的好方法。

有谁知道这样做的好方法?我正在用 C 编程,我的编译器是 gcc 版本 4.3.2。

感谢你的帮助。

0 投票
1 回答
1618 浏览

c - 64 位特定 simd 内在

我在 SSE2 中使用以下联合声明。

这个想法是为每个 a 和 b 分配两个无符号长变量(64 位长),对它们进行异或并将结果放在 c 中。

显式赋值 ( a.data[0] = something) 在这里有效,但需要更多时间。

我打算使用内在函数。如果我使用_mm_set_epi64 (unsigned long x, unsigned long y),它会要求__m64变量。如果我转换这些变量(__m64)x并且它工作正常,但它给出了错误的结果。

上面的代码给出了错误:

您能否建议一些替代方案(内在)?

0 投票
4 回答
4072 浏览

c - SIMD 代码比标量代码运行得慢

elma并且elmc都是unsigned long数组。res1和 也是如此res2

在 for 循环中包含元素 XOR 的非 simd 和 simd 版本。第二个 for 循环中的前两行执行显式 XOR,而其余行实现相同操作的 simd 版本。

此循环从外部调用数百次,因此优化此循环将有助于减少总计算时间。

问题是 simd 代码的运行速度比标量代码慢很多倍。

编辑:完成部分展开

但是,结果并没有太大变化;它仍然需要两倍的标量代码。

0 投票
2 回答
2443 浏览

c - SIMD 代码与标量代码

以下循环执行了数百次。
elma and elmc are both unsigned long (64-bit) arrays, so is res1 and res2.

在 for 循环中,标量版本的代码(已注释)运行速度是 simd 代码的两倍。下面提到了上述行的 cachegrind 输出(指令读取)。

行1:668,460,000 2 2
行2:668,460,000 1 1 1
行3:89,985,000 1 1 1 1
行4:89,985,000 1 1 1 1
行5:617,040,000 2 2行2
行6:44,992,500 0 0 0 0 LINE 0
LINE 7:44,992,500 0 0
LINE LINE LINE 8:44,992,500 0
LINE : : 128,550,000 0 0
第 10 行: . . .
第 11 行:205,680,000 0 0
第 12 行:205,680,000 0 0

从上图中可以看出,注释(标量代码)所需的指令数量明显少于 simd 代码。

如何使这段代码更快?

0 投票
1 回答
776 浏览

gcc - 较高级别的 SSE 标志是否暗示 GCC / clang 中的较低级别?

例如,如果您使用 -msse4,这是否意味着它也将使用 -mssse3、-msse3、-msse2 等等,或者您是否也必须显式添加这些标志?

0 投票
2 回答
6944 浏览

c++ - 对齐类型和按值传递参数

按值传递对齐类型或具有对齐类型的结构不适用于某些实现。这会破坏 STL 容器,因为某些方法(例如调整大小)按值获取它们的参数。

我使用 Visual Studio 2008 运行了一些测试,但不完全确定按值传递何时以及如何失败。我主要关心的是函数foo。它似乎工作正常,但它可能是内联或其他巧合的结果吗?如果我将其签名更改为void foo(const __m128&)怎么办?

非常感谢您的意见。谢谢你。

编辑。即使使用对齐的分配器,STL 也会失败,因为传递值问题仍然存在。

发现此链接按值传递 __m128

0 投票
1 回答
6100 浏览

c++ - SSE:将 __m128 和 __m128i 转换为两个 __m128d

两个相关的问题。

这就是我的代码需要对大量数据执行的操作。它是在内部循环中完成的,性能很重要。

  1. 将 __int32 和数组转换为双精度数(或将 __m128i 转换为两个 __m128d)。
  2. 将浮点数和数组转换为双精度数(或将 __m128 转换为两个 __m128d)。

基本上,我需要具有以下签名的函数:

输入输出指针对齐,元素个数为4的倍数。主要问题是如何快速将__m128解包成两个__m128d。