我有以下类型的代码
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,那么整体性能并不是更好,但等待在每次访问之间平均分配,而不是仅仅按第一次访问.
这里是介绍如何使用现代的x86-64处理器中内置的CRC32指令来计算最大1024个字节CRC32的文章.但是,我需要计算超过1024字节的CRC32.计算每个1024字节块的CRC32并最终求和它们是否是正确的方法,还是不正确?如果是这样,那么正确的方法是什么?
假设我有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)
我怎样才能做到这一点?
基于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) 我需要编写矩阵向量和矩阵乘法函数,但我无法绕过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
我只是在Xeon Phi处理器中读取AVX内置的AVX512集,但似乎sse中的传统数据类型转换方法在avx512中不起作用,所以我可以问一下avx512中是否有任何类似的cpu设置可以转换unsigned char数组到短数据类型数组?提前致谢!
我正在尝试将一个向量加载到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).谢谢
我有一个功能:
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.但它们没有向量化乘法的矢量化操作.或许我错了?
也许有人知道解决这个问题的任何可能性吗?
我__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.
非常感谢.
我有两个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)来完成它。