相关疑难解决方法(0)

在x86上做水平浮点矢量和的最快方法

你有一个三(或四)个浮点数的向量.总结它们的最快方法是什么?

SSE(movaps,shuffle,add,movd)总是比x87快吗?SSE4.2中的水平加法说明值得吗?移动到FPU的成本是多少,然后是faddp,faddp?什么是最快的特定指令序列?

"尝试安排事情,这样你可以一次总结四个向量"将不被接受作为答案.:-)

floating-point optimization x86 assembly sse

41
推荐指数
4
解决办法
2万
查看次数

为什么mulss在Haswell上只用了3个周期,与Agner的指令表不同?

我是指令优化的新手.

我对一个简单的函数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 …

c optimization assembly sse micro-optimization

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

英特尔AVX:256位版本的点积,用于双精度浮点变量

英特尔高级矢量扩展指令集(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)

c++ performance simd avx

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

为什么gcc不将_mm256_loadu_pd解析为单个vmovupd?

我正在编写一些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.0Ubuntu的18.04 X86-64.

assembly gcc simd vectorization avx

13
推荐指数
2
解决办法
464
查看次数

带SIMD的矢量点积

我试图使用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)

c x86 simd avx

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