标签: sse

simd存储延迟

我有以下类型的代码

short v[8] __attribute__ (( aligned(16)));
...
// in an inlined function :
_mm_store_si128(v, some_m128i_value);
... // some more operation (4 additions )
outp[0] = v[1] / 2; // <- first access of v since the previous store 
Run Code Online (Sandbox Code Playgroud)

当我用perf注释这个代码时,这一行占整个采样的18%!当我说行时,它处于汇编级别,即从v计数移动18%后的指令

它是缓存未命中吗?我怎么测试呢?

我真的不需要存储结果,但是如何避免往返内存,并且仍然单独访问组成我的m128i值的8短路.

更新:如果我使用_mm_extract_epi16,那么整体性能并不是更好,但等待在每次访问之间平均分配,而不是仅仅按第一次访问.

c gcc sse simd

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

计算大型CRC32的正确方法是什么?

这里是介绍如何使用现代的x86-64处理器中内置的CRC32指令来计算最大1024个字节CRC32的文章.但是,我需要计算超过1024字节的CRC32.计算每个1024字节块的CRC32并最终求和它们是否是正确的方法,还是不正确?如果是这样,那么正确的方法是什么?

c crc32 sse x86-64

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

如何使用SSE2加载16 x 8位整数

假设我有16个8位整数,我想将它们加载到__m128i使用SSE2中:

__m128i v = _mm_set_epi8(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16);
Run Code Online (Sandbox Code Playgroud)

我可以静态使用,_mm_set_epi8但我想动态地这样做; 值将在运行时决定.

C = userinput;
for(int i=0; i<16; i++)
{
    load C*i on v at position i
}
Run Code Online (Sandbox Code Playgroud)

我怎样才能做到这一点?

x86 sse simd sse2

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

无符号长整型数组的sse和

基于SSE浮点向量的减少,我试图对无符号长数组求和,但是很不幸,没有成功。

uint64_t vsum_uint64 (uint64_t *a, int n)
{
    uint64_t sum;    // lets say sum fits
    __m128 vsum = _mm_set1_ps(0);

    for (int i = 0; i < n; i += 2) {    // 2 unit64 in single __m128
        __m128 v = _mm_loadl_epi64(&a[i]);
        vsum = _mm_add_epi64(vsum, v);
    }

    _mm_store_ss(&sum, vsum);
    uint64_t *p = &vsum;
    sum+=*(p+1);

    // vsum = _mm_hadd_ps(vsum, vsum);
    // vsum = _mm_hadd_ps(vsum, vsum);
    return sum;
}
Run Code Online (Sandbox Code Playgroud)

这应该是正确的,但是gcc仍然无法编译它。我搜索了答案,但没有找到答案。

这就是gcc所说的:

main.cpp: In function ‘uint64_t vsum_uint64(const uint64_t*, int)’:
main.cpp:73:35: …
Run Code Online (Sandbox Code Playgroud)

c++ sse sum simd uint64

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

使用SSE的矩阵向量和矩阵 - 矩阵乘法

我需要编写矩阵向量和矩阵乘法函数,但我无法绕过SSE命令.

矩阵和向量的维数总是4的倍数.

我设法编写了矢量矢量乘法函数,如下所示:

void vector_multiplication_SSE(float* m, float* n, float* result, unsigned const int size)
{
    int i;

    __declspec(align(16))__m128 *p_m = (__m128*)m;
    __declspec(align(16))__m128 *p_n = (__m128*)n;
    __declspec(align(16))__m128 *p_result = (__m128*)result;

    for (i = 0; i < size / 4; ++i)
        p_result[i] = _mm_mul_ps(p_m[i], p_n[i]);

    // print the result
    for (int i = 0; i < size; ++i)
    {
        if (i % 4 == 0) cout << endl;
        cout << result[i] << '\t';
    }
}
Run Code Online (Sandbox Code Playgroud)

现在我正在尝试实现矩阵向量乘法.

这是我到目前为止所拥有的:

void multiply_matrix_by_vector_SSE(float* m, float* v, …
Run Code Online (Sandbox Code Playgroud)

c++ sse intrinsics matrix-multiplication vector-multiplication

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

任何方法将基于AVX512 cpu intrinics的unsigned char转换为short?

我只是在Xeon Phi处理器中读取AVX内置的AVX512集,但似乎sse中的传统数据类型转换方法在avx512中不起作用,所以我可以问一下avx512中是否有任何类似的cpu设置可以转换unsigned char数组到短数据类型数组?提前致谢!

sse simd xeon-phi avx512

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

将Vector加载到SSE寄存器中

我正在尝试将一个向量加载到SSE寄存器中,我的代码编译没有错误,但是当我尝试运行它时,我有分段错误.这是我的代码:

inline int SSEJaccard::calcSSEJaccardDist(unsigned int id1, unsigned int id2) {
  int result;
  __m128i v, v1;
  std::vector<uint32_t> &fv1 = fvs[id1];
  std::vector<uint32_t> &fv2 = fvs[id2];
  v = _mm_load_si128((__m128i const*) (&fv1));
  v1 = _mm_load_si128((__m128i const*) (&fv2));
  v = _mm_and_si128(v,v1);
  result =_mm_extract_epi16(v, 0) + _mm_extract_epi16(v, 4);
 return result;
}
Run Code Online (Sandbox Code Playgroud)

fsv是一个全局变量,定义如下:

std::vector<std::vector<uint32_t> > fvs;
Run Code Online (Sandbox Code Playgroud)

我正在使用英特尔编译器(ICC).谢谢

c++ x86 sse vector vectorization

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

模乘法的矢量化

我有一个功能:

void Func(const int * a, const int * b, size_t size, int p, int * c)
{
    for (size_t i = 0; i < size; ++i)
        c[i] = (a[i]*b[i])%p;
}
Run Code Online (Sandbox Code Playgroud)

此函数对整数数组执行许多模乘.所有整数都是正数.我需要提高其性能.

我想到了SSE和AVX.但它们没有向量化乘法的矢量化操作.或许我错了?

也许有人知道解决这个问题的任何可能性吗?

c++ algorithm sse simd avx

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

__int128对齐段故障与gcc -O SSE优化

__int128用作struct的成员.它可以找到-O0(没有优化).

但是,如果启用了优化(-O1),则会因段故障而崩溃.

它在指令处崩溃movdqa,需要将var对齐16,而地址的分配malloc()仅由8对齐.

我尝试禁用SSE优化-mno-sse,但无法编译:

/usr/include/x86_64-linux-gnu/bits/stdlib-float.h:27:1: error: SSE register return with SSE disabled
Run Code Online (Sandbox Code Playgroud)

所以,我能做些什么,如果我想使用__int128-O1两者兼而有之?

在此先感谢吴

顺便说一下,如果__int128仅在堆栈上使用(不在堆上),似乎没问题.

====编辑====

对不起,我没说实话.

其实我没用过malloc().我使用了一个内存池lib,它返回8对齐的地址.我说malloc()只是为了让事情变得简单.

经过测试,我已经知道它malloc()与16对齐.并且__int128成员也在结构中对齐16.

所以问题是我的内存池lib.

非常感谢.

gcc sse memory-alignment compiler-optimization

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

使用SSE的任意位置2输入改组

我有两个4分量向量,我将它们加载到两个__m128变量中。然后,我需要将它们洗牌,以便结果看起来像这样:

鉴于:

__m128 mmMin = _mm_load_ps(&glm::vec4(-1.0f,-2.0f,-3.0f,-4.0f)[0]);
__m128 mmMax = _mm_load_ps(&glm::vec4(1.0f,2.0f,3.0f,4.0f)[0]);
Run Code Online (Sandbox Code Playgroud)

我希望改组的结果看起来像这样:

 //    {mmMin.x,mmMax.x,mmMin.x,mmMax.x}
Run Code Online (Sandbox Code Playgroud)

但是我认为这是不可能的_mm_shuffle_ps

SSE文档中,我看到 _mm_shuffle_ps 遮罩总是先从__m128的低2个分量插入结果2值,然后从高2个分量插入2值。

SPU内在函数具有si_shufb允许定义qword基于蒙版和随机播放我希望的任何位置的方法。SSE中有类似的方法吗?

我正在使用SSE2,但也很高兴看到如何使用其他版本(包括AVX)来完成它。

c++ sse simd avx

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