问题标签 [sse2]
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.
c++ - sse 类型的数组:Segmentation Fault
今天我尝试初始化一个 sse 类型 __m128d 的数组。不幸的是它没有用 - 为什么?通常不可能创建 sse 类型的数组(因为它们是寄存器类型?)。以下代码在循环中的分配处出现段错误。
问候 + 繁荣
gcc - GCC 对 XMM 寄存器的支持严重损坏?
每当我检查 GCC 为使用 __m128i 类型的代码生成的汇编代码时,我都会看到看起来像是一场灾难。有大量无用的冗余指令。
然而,作为一名汇编程序员,我宁愿使用 asm{},但 GCC 阻止我在 asm{} 中使用 XMM 寄存器。
让 GCC 使用 XMM 是否有一些技巧,或者我需要等待未来的版本吗?我有 4.3.4。
assembly - 对有符号整数内的元组进行排序
我正在使用 SSE2 将 16+16 位元组排序为 32 位整数。比较和最小值/最大值只有带符号的整数指令。我对较高部分的顺序没有问题,因为它只是一个哈希。但是带有负哈希的条目将被向后排序(对吗?)可能但不是很好的解决方案可能是:
- 将哈希的较高位归零,失去精度(不是很好)
- 如果设置了哈希的较高位,则将位置转换为负数,并在排序后将其转换回来。
有没有更好的办法?
optimization - 调整 MIT 的 bitcount 算法以并行计算单词?
我想使用著名的 MIT 位计数算法的一个版本,使用 SSE2 指令计算康威生命游戏中的邻居。
这是 c 中的 MIT 位计数,扩展到计数位计数 > 63 位。
这是帕斯卡的一个版本
我正在寻找并行计算此结构中的位。
注意这个结构中间有 16 位需要查找。我想使用 SSE2计算中间 16 位中的每一位的邻居计数。为了做到这一点,我将切片 A 放入 XMM0 低位双字中,切片 B 放入 XXM0-dword1 等。
我将 XMM0 复制到 XMM1 并屏蔽XMM0 的低位字中的012-456-89A
位5
,对 XMM0 的字1 执行相同操作,等等。使用不同的切片和掩码来确保 XMM0 和 XMM1 中的每个单词都包含不同像素的邻居。
问题
如何调整 MIT-bitcount 以在每个 XMM 字中得到每个字/像素的位计数?
备注
我不想使用查找表,因为我已经有了这种方法,我想测试一下 SSE2 是否会通过不需要对查找表进行内存访问来加快进程。
使用 SSE 汇编的答案将是最佳的,因为我在 Delphi 中对此进行了编程,因此我使用的是 x86+SSE2 汇编代码。
c - 哪个更快?
我在 gcc 4.4.3 中使用 SSE2。在我的程序中,我需要使用至少 (0 - 7) 个 8 位的 128 位 SIMD 寄存器。请提出一种我可以快速检索 8 位的方法。
我尝试使用_mm_movepi64_pi64
or _mm_extract_epi16
,这两者在我的程序中都提供了相似的性能。我也在尝试联合方法。union{__m128i a1, int a2[4]}
. 虽然,在测试用例中,它给出了很好的结果,但在我的程序中,这种方法并不是很好。
任何想法..(我应该使用上述三种方法中的哪一种?)
c++ - 严格别名和 __m128i 类型
当使用 SSE2 内部函数进行按位操作时,必须将指针从int*
to 转换为__m128i*
. 此代码是否违反严格的别名规则?
谢谢!
optimization - 用于优化向量位移的汇编代码
我正在尝试编写一个例程,该例程将以最有效的方式将向量的所有元素向右移动 n 个位置,以适用于以下向量类型:BYTE->BYTE、WORD->WORD、DWORD->DWORD 和WORD->BYTE(假设结果中只有 8 位)。我想根据处理器的类型为每种类型设置三个例程(支持 SSE2,仅支持 MMX,仅支持标准指令 se)。因此我总共需要 12 个函数。
我自己已经找到了如何备份和恢复我需要的寄存器,如何进行循环,如何将数据复制到常规寄存器或 MMX 寄存器以及如何在逻辑上移位 1 个位置。
因为我不熟悉它的汇编语言。我应该为每个指令集使用哪些寄存器?如何优化 L1 缓存中大矢量(图像)的可用性?我如何找到向量的下一个元素(指针之类的东西),我知道我可以按地址制作一个 mov,并且我假设我必须根据我的数据类型将地址增加 1、2 或 4?
虽然我有所有的想法,但在这一点上编写代码有点困难。
谢谢你。
阿尔诺。
编辑:这是我试图为 MMX 在 DWORD 上移动 1 所做的事情:
c++ - SSE2 双倍乘法比标准乘法慢
我想知道为什么带有 SSE2 指令的以下代码执行乘法比标准 C++ 实现慢。这是代码:
m_output.data
和的内存input().data
已使用 _aligned_malloc 分配。
然而,对于 2^25 数组执行此代码的时间与此代码的时间相同(350 毫秒):
这怎么可能?理论上应该只需要 50% 的时间,对吧?还是从 SIMD 寄存器到 m_output.data 数组的内存传输开销如此昂贵?
如果我替换第一个片段中的行
经过
然后__m128d tmp;
代码执行得非常快,比我的计时器功能的分辨率要低。那是因为一切都只存储在寄存器中而不是内存中吗?
更令人惊讶的是,如果我在调试模式下编译,SSE 代码只需要 93ms而标准乘法需要309ms。
- 调试:93ms (SSE2) / 309ms(标准乘法)
- RELEASE:350ms (SSE2) / 350(标准乘法)
这里发生了什么???
我在发布模式下使用带有 QtCreator 2.2.1 的 MSVC2008。这是我的 RELEASE 编译器开关:
这些是用于调试的:
编辑 关于 RELEASE 与 DEBUG 问题:我只想指出我分析了代码,而 SSE 代码在发布模式下实际上速度较慢! 这只是以某种方式证实了 VS2008 无法正确处理优化器的内在函数的假设。英特尔 VTune 在 DEBUG 中为 SSE 循环提供了 289 毫秒,在 RELEASE 模式下为我提供了 504 毫秒。哇...只是哇...
c++ - Visual Studio 2010 和 SSE 4.2
我想知道,在 Visual Studio 2010 中设置什么才能启用 SSE 4.2?我想使用它是因为优化了 POPCNT...
如果所有设置都正常,我该如何测试?
谢谢
好吧,我尝试使用您的解决方案,但是<nmmintric.h>
不包含在 vstudio2010 和标准__popcnt
要求中int
,而不是std::bitset<>
:(
任何想法?
感谢带有正确标题的提示。但是,似乎:error C3861: '_mm_popcnt_u64': identifier not found
,我只找到了_mm_popcnt_u32
,但是我不知道如何将它与 一起使用bitset
,还是应该只使用bitset<>.count
?如果没有编译器的 anz 设置,它就无法工作,可以吗?
没人知道 ?
visual-studio - Visual Studio 可以告诉我已编译代码的 SSE2 寄存器溢出计数吗?
我没有任何真正的编译器知识,我曾经为选定的代码片段手动编写 SSE2 函数。我知道如何阅读生成的机器代码,但很大程度上不知道编译器可能进行的疯狂优化。我所有的工作都是使用 Visual Studio 完成的。
Visual Studio 有没有办法告诉我一个函数的 SSE2 寄存器溢出计数?原因是我们很快就能批量生产类似 SSE2 的代码(模板化),并且我们希望将它们中的每一个都编译成质量不错的机器代码。我们可能无法手动检查它们中的每一个。我希望得到的是某种保证,即编译后的代码是可接受且简洁的。我不需要得到最后一点果汁。
或者,是否有一个关键字可以__forceinline
强制编译器不溢出任何 SSE2 寄存器,例如 "__forcenospill" ?(如果必须发生溢出,编译将失败,因此我会意识到问题并尝试重构我的 SSE2 代码。)
使用现有的向量库或 blitter 是没有问题的,因为某些计算需要高度注册(“简单操作”中的一步中的 6 个或更多操作数(注 #1);中间值提升为 16 位或 32 位即时和转换回来等)用通用矢量库重新表述它意味着运行时间增加一倍或三倍(在那里,做到了)。
商业工具也可以,考虑到项目的性质,我当然可以负担得起。
如果没有这样的工具,我将求助于分析。你可以对这篇文章投反对票,让我知道这样的事情不存在。
谢谢!
(注#1)它是一种自适应阈值算法。