使用SSE加速计算 - 存储,加载和对齐

use*_*521 8 c++ sse

在我的项目中,我实现了基本的类CVector.该类包含指向原始浮点数组的float*指针.使用标准malloc()函数动态分配此数组.

现在我必须使用这样的向量加速一些计算.不幸的是,因为内存没有使用_mm_malloc()进行分配,所以它没有对齐.

据我所知,我有两个选择:

1)重写代码,分配内存以使用_mm_malloc(),例如使用如下代码:

void sub(float* v1, float* v2, float* v3, int size) 
{  
    __m128* p_v1 = (__m128*)v1;  
    __m128* p_v2 = (__m128*)v2;  
    __m128 res;

    for(int i = 0; i < size/4; ++i)  
    {  
        res = _mm_sub_ps(*p_v1,*p_v2);  
        _mm_store_ps(v3,res);  
        ++p_v1;  
        ++p_v2;  
        v3 += 4;  
    }
}
Run Code Online (Sandbox Code Playgroud)

2)第二个选项是使用_mm_loadu_ps()指令从未对齐的内存加载__m128,然后将其用于计算.

void sub(float* v1, float* v2, float* v3, int size)
{  
    __m128 p_v1;  
    __m128 p_v2;  
    __m128 res;

    for(int i = 0; i < size/4; ++i)  
    {  
        p_v1 = _mm_loadu_ps(v1);   
        p_v2 = _mm_loadu_ps(v2);  
        res = _mm_sub_ps(p_v1,p_v2);    
        _mm_store_ps(v3,res);  
        v1 += 4;  
        v2 += 4;  
        v3 += 4;  
    }
}
Run Code Online (Sandbox Code Playgroud)

所以我的问题是哪个选项会更好还是更快?

Han*_*ant 15

读取未对齐的SSE值非常昂贵.查看英特尔手册,第4卷,第2.2.5.1章.核心类型有所不同,i7具有额外的硬件,使其成本更低.但是读取跨越cpu缓存行边界的值仍然比读取对齐值慢4.5倍.这是10以前的架构慢倍.

这是巨大的,让内存对齐,以避免这种性能.从未听说过_mm_malloc,请使用Microsoft CRT中的_aligned_malloc()从堆中获取正确对齐的内存.

  • 好答案.我期待在这里只找到"描述你的代码"答案...... (6认同)