标签: simd

SIMD编程语言

在过去的几年里,我一直在做很多SIMD编程,大多数时候我一直依赖于编译器内部函数(例如用于SSE编程的函数)或编程汇编来实现真正的俏皮东西.但是,到目前为止,我几乎找不到任何内置支持SIMD的编程语言.

现在显然有一些着色器语言,如HLSL,Cg和GLSL,它们对这种东西有本机支持,但是,我正在寻找能够至少在没有自动向量化的情况下编译到SSE但内置支持向量操作的东西.这种语言存在吗?

这是(部分)Cg着色器的一个例子,它做了一个聚光灯,在语法方面,这可能是我最接近我正在寻找的.

float4 pixelfunction(
    output_vs IN, 
    uniform sampler2D texture : TEX0, 
    uniform sampler2D normals : TEX1, 
    uniform float3 light, 
    uniform float3 eye ) : COLOR
{
    float4 color    = tex2D( texture, IN.uv );
    float4 normal   = tex2D( normals, IN.uv ) * 2 - 1;

    float3 T = normalize(IN.T);
    float3 B = normalize(IN.B);

    float3 N = 
        normal.b * normalize(IN.normal) +
        normal.r * T +
        normal.g * B;

    float3 V = normalize(eye - IN.pos.xyz);
    float3 L = normalize(light - IN.pos);
    float3 …
Run Code Online (Sandbox Code Playgroud)

programming-languages sse simd ispc

11
推荐指数
3
解决办法
3300
查看次数

可以矢量化myNum + = a [b [i]]*c [i]; 在x86_64上?

我将使用什么内在函数来对x86_64上的以下内容进行矢量化(如果它甚至可以进行矢量化)?

double myNum = 0;
for(int i=0;i<n;i++){
    myNum += a[b[i]] * c[i]; //b[i] = int, a[b[i]] = double, c[i] = double
}
Run Code Online (Sandbox Code Playgroud)

x86 sse x86-64 simd vectorization

11
推荐指数
2
解决办法
1151
查看次数

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

我正在使用SSE内在函数为英特尔x86 Nehalem微架构优化一些代码.

我的程序的一部分计算4个点产品,并将每个结果添加到阵列的连续块中的先前值.进一步来说,

tmp0 = _mm_dp_ps(A_0m, B_0m, 0xF1);
tmp1 = _mm_dp_ps(A_1m, B_0m, 0xF2);
tmp2 = _mm_dp_ps(A_2m, B_0m, 0xF4);
tmp3 = _mm_dp_ps(A_3m, B_0m, 0xF8);

tmp0 = _mm_add_ps(tmp0, tmp1);
tmp0 = _mm_add_ps(tmp0, tmp2);
tmp0 = _mm_add_ps(tmp0, tmp3);
tmp0 = _mm_add_ps(tmp0, C_0n);

_mm_storeu_ps(C_2, tmp0);
Run Code Online (Sandbox Code Playgroud)

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

tmp0 = R0-零 - 零

tmp1 =零-R1-零

tmp2 =零 - 零 - 零

tmp3 =零 - 零 - R3

我将每个tmp变量中包含的值组合成一个xmm变量,并将它们与以下说明相加:

tmp0 = _mm_add_ps(tmp0, tmp1);
tmp0 = _mm_add_ps(tmp0, tmp2);
tmp0 = _mm_add_ps(tmp0, tmp3);
Run Code Online (Sandbox Code Playgroud)

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

tmp0 = _mm_add_ps(tmp0, …
Run Code Online (Sandbox Code Playgroud)

c sse simd intrinsics dot-product

11
推荐指数
1
解决办法
3178
查看次数

gcc,simd内在函数和快速数学概念

大家好:)
我试图抓住一些关于浮点,SIMD /数学内在函数和gcc的快速数学标志的概念.更具体地说,我在x86 cpu上使用MinGW和gcc v4.5.0.

我现在已经搜索了一会儿,这就是我(我想)我现在所理解的:

当我没有标志编译时,任何fp代码将是标准x87,没有simd内在函数,math.h函数将从msvcrt.dll链接.

当我使用mfpmath,mssen和/或march使得mmx/sse/avx代码被启用时,gcc实际上只有在我还指定一些优化标志时才使用simd指令,如Onftree-vectorize.在这种情况下,内部函数是由gcc自动选择的,并且一些数学函数(我仍在谈论math.h上的标准数学函数)将成为内在函数或通过内联代码进行优化,其他函数仍将来自msvcrt. DLL.如果我没有指定优化标志,这会改变吗?

当我使用特定的simd数据类型(那些可用作gcc扩展,如v4siv8qi)时,我可以选择直接调用内部函数,或者再次将自动决定留给gcc.如果我没有通过正确的标志启用simd指令,Gcc仍然可以选择标准的x87代码.同样,如果我没有指定优化标志,这会改变吗?

如果我的任何陈述错误,请纠正我:p

现在的问题是:

  1. 我是否必须包含x86intrin.h才能使用内在函数?
  2. 我是否必须链接libm?
  3. 什么快速数学与任何东西有关?我理解它放宽了IEEE标准,但具体来说,如何?使用其他标准功能?其他一些lib链接?或者只是在某处设置了几个标志,标准的lib表现不同?

感谢任何想要帮助的人:D

gcc simd intrinsics fast-math

11
推荐指数
1
解决办法
4472
查看次数

SSE乘法16 x uint8_t

我想用SSE4乘以一个__m128i带有16个无符号8位整数的对象,但我只能找到一个乘以16位整数的内在函数.有没有这样的_mm_mult_epi8

x86 sse simd sse4

11
推荐指数
3
解决办法
7134
查看次数

SSE:将短整数转换为float

我想使用SSE将无符号短数组转换为float.让我们说吧

__m128i xVal;     // Has 8 16-bit unsigned integers
__m128 y1, y2;    // 2 xmm registers for 8 float values
Run Code Online (Sandbox Code Playgroud)

我希望y1中的前4个uint16和y2中的下一个4 uint16.需要知道哪些内在使用.

x86 sse simd

11
推荐指数
2
解决办法
8640
查看次数

快速计算两个数组之间的相等字节数

我编写了该函数int compare_16bytes(__m128i lhs, __m128i rhs),以便使用SSE指令比较两个16字节数:该函数返回执行比较后相等的字节数.

现在我想使用上面的函数来比较任意长度的两个字节数组:长度可能不是16字节的倍数,所以我需要处理这个问题.我怎样才能完成下面这个功能的实现?我怎样才能改进下面的功能?

int fast_compare(const char* s, const char* t, int length)
{
    int result = 0;

    const char* sPtr = s;
    const char* tPtr = t;

    while(...)
    {
        const __m128i* lhs = (const __m128i*)sPtr;
        const __m128i* rhs = (const __m128i*)tPtr;

        // compare the next 16 bytes of s and t
        result += compare_16bytes(*lhs,*rhs);

        sPtr += 16;
        tPtr += 16;
    }

    return result;
}
Run Code Online (Sandbox Code Playgroud)

c c++ sse simd sse2

11
推荐指数
1
解决办法
1459
查看次数

快速计算__m128i寄存器中的设置位数

我应该计算__m128i寄存器的设置位数.特别是,我应该使用以下方法编写两个能够计算寄存器位数的函数.

  1. 寄存器的设定位总数.
  2. 寄存器的每个字节的设置位数.

是否有可以完全或部分执行上述操作的内在功能?

c c++ sse simd sse2

11
推荐指数
1
解决办法
7469
查看次数

浮点相等比较的SIMD指令(NaN == NaN)

哪些指令用于比较由4*32位浮点值组成的两个128位向量?

是否存在将双方的NaN值视为相等的指令?如果不是,提供反身性的解决方案(即NaN等于NaN)的性能影响有多大?

我听说,与IEEE语义相比,确保反身性会产生显着的性能影响,因为NaN不等于自己,我想知道这种影响是否会很大.

我知道您在处理浮点值时通常需要使用epsilon比较而不是精确的质量.但是这个问题是关于完全相等的比较,例如,您可以使用它来消除哈希集中的重复值.

要求

  • +0并且-0必须相等.
  • NaN 必须与自己相等.
  • NaN的不同表示应该相等,但如果性能影响太大,可能会牺牲该要求.
  • true如果两个向量中的所有四个float元素相同,则结果应为布尔值,如果至少一个元素不同,则结果为false.其中true由标量整数1falseby表示0.

测试用例

(NaN, 0, 0, 0) == (NaN, 0, 0, 0) // for all representations of NaN
(-0,  0, 0, 0) == (+0,  0, 0, 0) // equal despite different bitwise representations
(1,   0, 0, 0) == (1,   0, 0, 0)
(0,   0, 0, 0) != (1,   0, 0, 0) // at least one different element => not equal …
Run Code Online (Sandbox Code Playgroud)

floating-point x86 assembly x86-64 simd

11
推荐指数
2
解决办法
1971
查看次数

打包和解交错两个__m256寄存器

我有一个行的行数组(~20 cols x~1M行),我需要一次从两个__m256寄存器中提取两列.

...a0.........b0......
...a1.........b1......
// ...
...a7.........b7......
// end first __m256
Run Code Online (Sandbox Code Playgroud)

一个天真的方法是这样做

__m256i vindex = _mm256_setr_epi32(
    0,
    1 * stride,
    2 * stride,
    // ...
    7 * stride);
__m256 colA = _mm256_i32gather_ps(baseAddrColA, vindex, sizeof(float));
__m256 colB = _mm256_i32gather_ps(baseAddrColB, vindex, sizeof(float));
Run Code Online (Sandbox Code Playgroud)

但是,我想知道我是否会通过a0, b0, a1, b1, a2, b2, a3, b3在一个中检索gathera4, b4, ... a7, b7在另一个中获得更好的性能,因为它们在内存中更接近,然后对它们进行反交错.那是:

// __m256   lo = a0 b0 a1 b1 a2 b2 a3 b3 // load proximal elements
// __m256   hi …
Run Code Online (Sandbox Code Playgroud)

c++ x86 simd avx avx2

11
推荐指数
1
解决办法
866
查看次数