标签: sse

使用AVX内在函数代替SSE并不能提高速度 - 为什么?

我已经使用英特尔的SSE内在函数已经有一段时间了,性能有了很好的提升.因此,我期望AVX内在函数能够进一步加速我的程序.不幸的是,直到现在情况并非如此.可能我犯了一个愚蠢的错误,所以如果有人能帮助我,我将非常感激.

我使用Ubuntu 11.10和g ++ 4.6.1.我编写了我的程序(见下文)

g++ simpleExample.cpp -O3 -march=native -o simpleExample
Run Code Online (Sandbox Code Playgroud)

测试系统配有Intel i7-2600 CPU.

这是代表我的问题的代码.在我的系统上,我得到输出

98.715 ms, b[42] = 0.900038 // Naive
24.457 ms, b[42] = 0.900038 // SSE
24.646 ms, b[42] = 0.900038 // AVX
Run Code Online (Sandbox Code Playgroud)

注意,仅选择计算sqrt(sqrt(sqrt(x)))以确保内存带宽不限制执行速度; 这只是一个例子.

simpleExample.cpp:

#include <immintrin.h>
#include <iostream>
#include <math.h> 
#include <sys/time.h>

using namespace std;

// -----------------------------------------------------------------------------
// This function returns the current time, expressed as seconds since the Epoch
// -----------------------------------------------------------------------------
double getCurrentTime(){
  struct timeval curr;
  struct timezone tz;
  gettimeofday(&curr, &tz);
  double tmp = …
Run Code Online (Sandbox Code Playgroud)

c++ performance gcc sse avx

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

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

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

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

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

floating-point optimization x86 assembly sse

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

如何确定内存是否对齐?

我是使用SSE/SSE2指令优化代码的新手,直到现在我还没有走得太远.据我所知,一个常见的SSE优化函数如下所示:

void sse_func(const float* const ptr, int len){
    if( ptr is aligned )
    {
        for( ... ){
            // unroll loop by 4 or 2 elements
        }
        for( ....){
            // handle the rest
            // (non-optimized code)
        }
    } else {
        for( ....){
            // regular C code to handle non-aligned memory
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

但是,如何正确确定内存ptr点是否与16字节对齐?我认为我必须包含非对齐内存的常规C代码路径,因为我无法确保传递给此函数的每个内存都将对齐.使用内在函数将数据从未对齐的内存加载到SSE寄存器似乎非常慢(甚至比常规C代码慢).

先感谢您...

c memory optimization sse simd

40
推荐指数
6
解决办法
4万
查看次数

矢量数据如何对齐?

如果我想std::vector用SSE 处理数据,我需要16字节对齐.我怎样才能做到这一点?我需要编写自己的分配器吗?或者默认分配器是否已经与16字节边界对齐?

c++ sse vector alignment allocator

40
推荐指数
3
解决办法
2万
查看次数

如何在SSE/AVX中使用融合乘法 - 加法(FMA)指令

我已经了解到一些Intel/AMD CPU可以同时进行多次复用并添加SSE/AVX:
每个周期的FLOPS用于沙桥和haswell SSE2/AVX/AVX2.

我想知道如何在代码中做到最好,我也想知道它是如何在CPU内部完成的.我的意思是超标量架构.假设我想做一个很长的总和,如下面的SSE:

//sum = a1*b1 + a2*b2 + a3*b3 +... where a is a scalar and b is a SIMD vector (e.g. from matrix multiplication)
sum = _mm_set1_ps(0.0f);
a1  = _mm_set1_ps(a[0]); 
b1  = _mm_load_ps(&b[0]);
sum = _mm_add_ps(sum, _mm_mul_ps(a1, b1));

a2  = _mm_set1_ps(a[1]); 
b2  = _mm_load_ps(&b[4]);
sum = _mm_add_ps(sum, _mm_mul_ps(a2, b2));

a3  = _mm_set1_ps(a[2]); 
b3  = _mm_load_ps(&b[8]);
sum = _mm_add_ps(sum, _mm_mul_ps(a3, b3));
...
Run Code Online (Sandbox Code Playgroud)

我的问题是如何将其转换为同时乘法并添加?数据可以依赖吗?我的意思是CPU可以_mm_add_ps(sum, _mm_mul_ps(a1, b1))同时执行还是在乘法中使用的寄存器和add必须是独立的?

最后,这如何适用于FMA(与Haswell)?是_mm_add_ps(sum, _mm_mul_ps(a1, b1))自动转换为单个FMA指令还是微操作?

c sse cpu-architecture avx fma

40
推荐指数
2
解决办法
3万
查看次数

为什么strcmp没有SIMD优化?

我试图在x64计算机上编译这个程序:

#include <cstring>

int main(int argc, char* argv[])
{
  return ::std::strcmp(argv[0],
    "really really really really really really really really really"
    "really really really really really really really really really"
    "really really really really really really really really really"
    "really really really really really really really really really"
    "really really really really really really really really really"
    "really really really really really really really really really"
    "really really really really really really really really really"
    "really really really really really really …
Run Code Online (Sandbox Code Playgroud)

c++ sse simd strcmp sse2

36
推荐指数
3
解决办法
7563
查看次数

英特尔SSE和AVX示例和教程

是否有用于学习英特尔SSE和AVX指令的优秀C/C++教程或示例?

我在微软MSDN和英特尔网站上发现很少,但从基础知识中理解它会很棒.

sse intel vectorization avx

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

有序/无序比较是什么意思?

看着SSE运营商

CMPORDPS - ordered compare packed singles
CMPUNORDPS - unordered compare packed singles
Run Code Online (Sandbox Code Playgroud)

有序和无序是什么意思?我在x86指令集中寻找等效指令,它似乎只有无序(FUCOM).

x86 assembly sse

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

如果没有Skylake上的VZEROUPPER,为什么这个SSE代码会慢6倍?

我一直试图找出应用程序中的性能问题,并最终将其缩小到一个非常奇怪的问题.如果VZEROUPPER指令被注释掉,则下面的代码在Skylake CPU(i5-6500)上运行速度慢6倍.我测试了Sandy Bridge和Ivy Bridge CPU,两种版本都以相同的速度运行,有或没有VZEROUPPER.

现在我VZEROUPPER对这个代码有了一个相当好的想法,而且我认为当没有VEX编码指令并且没有调用可能包含它们的任何函数时,它对这个代码根本不重要.事实上它不支持其他支持AVX的CPU似乎支持这一点.英特尔®64和IA-32架构优化参考手册中的表11-2也是如此

那么发生了什么?

我留下的唯一理论是,CPU中存在一个错误,它错误地触发了"保存AVX寄存器的上半部分"程序,而不应该这样做.或者其他一些同样奇怪的东西.

这是main.cpp:

#include <immintrin.h>

int slow_function( double i_a, double i_b, double i_c );

int main()
{
    /* DAZ and FTZ, does not change anything here. */
    _mm_setcsr( _mm_getcsr() | 0x8040 );

    /* This instruction fixes performance. */
    __asm__ __volatile__ ( "vzeroupper" : : : );

    int r = 0;
    for( unsigned j = 0; j < 100000000; ++j )
    {
        r |= slow_function( 
                0.84445079384884236262,
                -6.1000481519580951328, …
Run Code Online (Sandbox Code Playgroud)

performance x86 sse intel avx

32
推荐指数
2
解决办法
4072
查看次数

为什么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
查看次数