你有一个三(或四)个浮点数的向量.总结它们的最快方法是什么?
SSE(movaps,shuffle,add,movd)总是比x87快吗?SSE4.2中的水平加法说明值得吗?移动到FPU的成本是多少,然后是faddp,faddp?什么是最快的特定指令序列?
"尝试安排事情,这样你可以一次总结四个向量"将不被接受作为答案.:-)
我是指令优化的新手.
我对一个简单的函数dotp进行了简单的分析,该函数用于获取两个浮点数组的点积.
C代码如下:
float dotp(
const float x[],
const float y[],
const short n
)
{
short i;
float suma;
suma = 0.0f;
for(i=0; i<n; i++)
{
suma += x[i] * y[i];
}
return suma;
}
Run Code Online (Sandbox Code Playgroud)
我用昂纳雾在网络上提供的测试框架testp.
在这种情况下使用的数组是对齐的:
int n = 2048;
float* z2 = (float*)_mm_malloc(sizeof(float)*n, 64);
char *mem = (char*)_mm_malloc(1<<18,4096);
char *a = mem;
char *b = a+n*sizeof(float);
char *c = b+n*sizeof(float);
float *x = (float*)a;
float *y = (float*)b;
float *z = (float*)c;
Run Code Online (Sandbox Code Playgroud)
然后我调用函数dotp,n = 2048,repeat …
英特尔高级矢量扩展指令集(AVX)在256位版本(YMM寄存器)中不提供双精度浮点变量的点积."为什么?" 问题已在另一个论坛(此处)和Stack Overflow(此处)进行了简要处理.但我面临的问题是如何以有效的方式用其他AVX指令替换这条缺失的指令?
对于单精度浮点变量,存在256位版本的点积(此处参考):
__m256 _mm256_dp_ps(__m256 m1, __m256 m2, const int mask);
Run Code Online (Sandbox Code Playgroud)
我们的想法是找到这个缺失指令的有效等价物:
__m256d _mm256_dp_pd(__m256d m1, __m256d m2, const int mask);
Run Code Online (Sandbox Code Playgroud)
更具体地说,我想从__m128(四个浮点数)转换为__m256d(4个双精度数)的代码使用以下指令:
__m128 val0 = ...; // Four float values
__m128 val1 = ...; //
__m128 val2 = ...; //
__m128 val3 = ...; //
__m128 val4 = ...; //
__m128 res = _mm_or_ps( _mm_dp_ps(val1, val0, 0xF1),
_mm_or_ps( _mm_dp_ps(val2, val0, 0xF2),
_mm_or_ps( _mm_dp_ps(val3, val0, 0xF4),
_mm_dp_ps(val4, …Run Code Online (Sandbox Code Playgroud) 我正在编写一些AVX代码,我需要从可能未对齐的内存中加载.我目前正在加载4个双打,因此我将使用内部指令_mm256_loadu_pd ; 我写的代码是:
__m256d d1 = _mm256_loadu_pd(vInOut + i*4);
Run Code Online (Sandbox Code Playgroud)
然后,我使用选项进行编译,-O3 -mavx -g然后使用objdump获取汇编代码以及带注释的代码和line(objdump -S -M intel -l avx.obj).
当我查看底层汇编程序代码时,我发现以下内容:
vmovupd xmm0,XMMWORD PTR [rsi+rax*1]
vinsertf128 ymm0,ymm0,XMMWORD PTR [rsi+rax*1+0x10],0x1
Run Code Online (Sandbox Code Playgroud)
我期待看到这个:
vmovupd ymm0,XMMWORD PTR [rsi+rax*1]
Run Code Online (Sandbox Code Playgroud)
并充分利用256位寄存器(YMM0),而不是它看起来像海湾合作委员会已决定在128位部分(填写XMM0),然后再次加载另一半vinsertf128.
有人能够解释这个吗?在MSVC VS 2012中
使用单个vmovupd编译等效代码.
我运行gcc (Ubuntu 7.3.0-27ubuntu1~18.04) 7.3.0在Ubuntu的18.04 X86-64.
我试图使用SIMD指令加速我的C代码中的点积计算.但是,我的函数的运行时间大致相等.如果有人能解释为什么以及如何加快计算,那就太棒了.
具体来说,我正在尝试计算两个数组的点积,其中包含大约10,000个元素.我的常规C函数如下:
float my_dotProd( float const * const x, float const * const y, size_t const N ){
// N is the number of elements in the arrays
size_t i;
float out=0;
for( i=0; i < N; ++i ){
out += x[i] * y[i];
}
return out;
}
Run Code Online (Sandbox Code Playgroud)
我使用AVX SIMD命令的功能如下:
void my_malloc( size_t nBytes, void ** ptrPtr ){
int boundary = 32;
posix_memalign( ptrPtr, boundary, nBytes );
}
float cimpl_sum_m128( __m128 x ){
float out;
__m128 sum = x;
sum …Run Code Online (Sandbox Code Playgroud)