标签: sse

x87优于SSE的优点

我知道x87具有更高的内部精度,这可能是人们在它与SSE操作之间看到的最大差异.但我不得不怀疑,使用x87还有其他好处吗?我有-mfpmath=sse在任何项目中自动输入的习惯,我想知道我是否遗漏了x87 FPU提供的任何其他内容.

x86 sse x86-64 fpu x87

24
推荐指数
4
解决办法
6600
查看次数

如何将128位立即数移动到XMM寄存器

关于这一点已经存在一个问题,但它被关闭为"含糊不清",所以我开了一个新的 - 我找到了答案,也许它也会帮助其他人.

问题是:如何编写汇编代码序列来初始化具有128位立即(常量)值的XMM寄存器?

x86 assembly sse simd

24
推荐指数
5
解决办法
2万
查看次数

SSE,内在函数和对齐

我使用了很多SSE编译器内在函数编写了一个3D矢量类.一切正常,直到我开始实现具有3D矢量作为新成员的类.我在发布模式下经历了奇怪的崩溃,但在调试模式下却没有,反之亦然.

所以我读了一些文章,并认为我需要将拥有3D矢量类实例的类对齐到16个字节.所以我只是在类之前添加了_MM_ALIGN16(__declspec(align(16)),如下所示:

_MM_ALIGN16 struct Sphere
{
    // ....

    Vector3 point;
    float radius
};
Run Code Online (Sandbox Code Playgroud)

这似乎首先解决了这个问题.但在更改了一些代码后,我的程序又开始以奇怪的方式崩溃.我在网上搜索了一些,发现了一篇博客文章.我尝试了作者Ernst Hot为解决这个问题做了什么,它对我也有用.我在我的类中添加了new和delete运算符,如下所示:

_MM_ALIGN16 struct Sphere
{
    // ....

    void *operator new (unsigned int size)
     { return _mm_malloc(size, 16); }

    void operator delete (void *p)
     { _mm_free(p); }

    Vector3 point;
    float radius
};
Run Code Online (Sandbox Code Playgroud)

恩斯特提到这种方法也可能存在问题,但他只是链接到一个不再存在的论坛,而没有解释为什么它可能会有问题.

所以我的问题是:

  1. 定义运算符有什么问题?

  2. 为什么不添加_MM_ALIGN16足够的类定义?

  3. 处理SSE内在函数的对齐问题的最佳方法是什么?

c++ sse alignment intrinsics

24
推荐指数
1
解决办法
1万
查看次数

在运行中生成矢量常数的最佳指令序列是什么?

"最佳"意味着最少的指令(或最少的uops,如果任何指令解码到多个uop).机器码大小(以字节为单位)是相同insn计数的平局.

恒定生成本质上是一个新的依赖链的开始,所以延迟很重要.在循环内生成常量也很不寻常,因此吞吐量和执行端口需求也几乎无关紧要.

生成常量而不是加载它们需要更多指令(除了全零或全一),因此它会占用宝贵的uop-cache空间.这可能是比数据缓存更有限的资源.

Agner Fog优秀的优化装配指南涵盖了这一点Section 13.4.表13.10具有用于产生向量序列,每一个元素是0,1,2,3,4,-1,或-2,与从8位到64位单元大小.表13.11具有用于产生一些浮点值序列(0.0,0.5,1.0,1.5,2.0,-2.0,和位掩码为符号位.)

Agner Fog的序列仅使用SSE2,无论是设计还是因为它尚未更新一段时间.

使用短的非显而易见的指令序列可以生成哪些其他常量? (具有不同移位计数的进一步扩展是显而易见的而不是"有趣的".)是否有更好的序列用于生成Agner Fog列出的常量?

如何将128位immediates移动到XMM寄存器说明了将任意128b常量放入指令流的一些方法,但这通常是不合理的(它不会节省任何空间,并占用大量的uop-cache空间.)

x86 assembly sse simd avx

24
推荐指数
1
解决办法
1733
查看次数

SSE向量包装器类型性能与裸__m128相比

我发现了一篇有趣的关于SIMD陷阱的Gamasutra文章,该文章指出__m128使用包装类型无法达到"纯" 类型的性能.我对此持怀疑态度,因此我下载了项目文件并制作了一个类似的测试用例.

事实证明(令我惊讶的是)包装版本明显变慢了.由于我不想谈论空气稀薄,测试案例如下:

在第一种情况下, Vec4是一个__m128带有一些运算符的类型的简单别名:

#include <xmmintrin.h>
#include <emmintrin.h>

using Vec4 = __m128;

inline __m128 VLoad(float f)
{
    return _mm_set_ps(f, f, f, f);
};

inline Vec4& operator+=(Vec4 &va, Vec4 vb)
{
    return (va = _mm_add_ps(va, vb));
};

inline Vec4& operator*=(Vec4 &va, Vec4 vb)
{
    return (va = _mm_mul_ps(va, vb));
};

inline Vec4 operator+(Vec4 va, Vec4 vb)
{
    return _mm_add_ps(va, vb);
};

inline Vec4 operator-(Vec4 va, Vec4 vb)
{
    return _mm_sub_ps(va, vb); …
Run Code Online (Sandbox Code Playgroud)

c++ optimization x86 assembly sse

23
推荐指数
1
解决办法
1277
查看次数

c ++ SSE SIMD框架

有谁知道一个开源的C++ x86 SIMD内在函数库?

英特尔在其集成性能原语库中提供了我所需要的,但由于版权所有,我无法使用它.

编辑

我已经知道编译器提供的内在函数了.我需要的是一个方便的界面来使用它们.

c++ sse simd intrinsics

22
推荐指数
4
解决办法
1万
查看次数

优化阵列压缩

假设我有一个数组 k = [1 2 0 0 5 4 0]

我可以按如下方式计算掩码 m = k > 0 = [1 1 0 0 1 1 0]

仅使用掩码m和以下操作

  1. 向左/向右移动
  2. 和/或
  3. 加/减/乘

我可以将k压缩成以下内容 [1 2 5 4]

这是我目前的做法(MATLAB伪代码):

function out = compact( in )
    d = in
    for i = 1:size(in, 2) %do (# of items in in) passes
        m = d > 0
        %shift left, pad w/ 0 on right
        ml = [m(2:end) 0] % shift
        dl = [d(2:end) 0] % shift

        %if …
Run Code Online (Sandbox Code Playgroud)

algorithm matlab sse simd

22
推荐指数
2
解决办法
2936
查看次数

打印__m128i变量

我正在尝试学习使用内在函数进行编码,下面是一个添加代码的代码

compiler used: icc

#include<stdio.h>
#include<emmintrin.h>
int main()
{
        __m128i a = _mm_set_epi32(1,2,3,4);
        __m128i b = _mm_set_epi32(1,2,3,4);
        __m128i c;
        c = _mm_add_epi32(a,b);
        printf("%d\n",c[2]);
        return 0;
}
Run Code Online (Sandbox Code Playgroud)

我得到以下错误:

test.c(9): error: expression must have pointer-to-object type
        printf("%d\n",c[2]);
Run Code Online (Sandbox Code Playgroud)

如何在c类型变量中打印值__m128i

c assembly sse simd intrinsics

21
推荐指数
3
解决办法
2万
查看次数

如何控制C数学是否使用SSE2?

我在fp:strict模式下使用MSVC进入了C库的超越数学函数的汇编.他们似乎都遵循相同的模式,这就是发生的事情sin.

首先,从名为"disp_pentium4.inc"的文件中有一个调度例程.它检查变量___use_sse2_mathfcns是否已设置; 如果是这样,电话__sin_pentium4,否则打电话__sin_default.

__sin_pentium4 (在"sin_pentium4.asm"中)首先将参数从x87 fpu传送到xmm0寄存器,使用SSE2指令执行计算,然后将结果加载回fpu.

__sin_default(在"sin.asm"中)将变量保存在x87堆栈上并简单地调用fsin.

因此,在这两种情况下,操作数推x87堆栈上和它返回为好,使之透明的来电,但如果___use_sse2_mathfcns被定义,在SSE2而不是的x87实际执行的操作.

这种行为是对我来说很有趣,因为的x87超越函数是臭名昭著的具有取决于实施的行为稍有不同,而SSE2的给定代码块要经常给重现的结果.

有没有办法确定在编译或运行时是否会使用SSE2代码路径?我不是很精通编写程序集,所以如果这涉及编写任何程序集,那么代码示例将不胜感激.

c++ floating-point sse deterministic visual-c++

21
推荐指数
1
解决办法
1784
查看次数

Intel cpu上的SIMD前缀和

我需要实现前缀和算法,并且需要它尽可能快.例如:

[3, 1,  7,  0,  4,  1,  6,  3]
Run Code Online (Sandbox Code Playgroud)

有没有办法使用SSE/mmx/SIMD cpu指令执行此操作?

我的第一个想法是递归并行地对每一对求和,直到所有的总和都计算如下!

[3, 4, 11, 11, 15, 16, 22, 25]
Run Code Online (Sandbox Code Playgroud)

为了使算法更清晰,"z"不是最终的输出

而是用来计算输出

//in parallel do 
for (int i = 0; i < z.length; i++) {
    z[i] = x[i << 1] + x[(i << 1) + 1];
}
Run Code Online (Sandbox Code Playgroud)

c++ sse simd prefix-sum

20
推荐指数
5
解决办法
6755
查看次数