使用SSE指令的图像最大值

时间:2014-02-02 12:46:34

标签: c++ sse

我试图使用SSE指令放弃一个返回图像最大值的函数。我有一个奇怪的结果,最大值设置为-356426400(值应为254)。

这是我的代码:

void max_sse(unsigned int *src, long h, long w, unsigned int *val)
{

unsigned int tab[16];
for(int i=0; i<h*w;i+=16)
{
__m128i PG=_mm_load_si128((__m128i*)(&src[i]));
__m128i max=_mm_max_epi8(max,PG);
_mm_store_si128((__m128i*)&tab, max);
}
*val=tab[0];
for (int i=0;i<16;i++)
{
if (tab[i]>*val)
{
*val=tab[i];
}
}

}

1 个答案:

答案 0 :(得分:3)

1)我没有看到任何处理对齐的代码

2)无符号整数与 _mm_max_epi8 之间存在不匹配,其中包含8位有符号整数(http://msdn.microsoft.com/en-us/library/bb514045(v=vs.90).aspx

3)我假设你有一个h * w矩阵,其行数为4(或者例如用一些填充处理)

在Windows上,您可以执行以下操作:

#include "windows.h"
#include <malloc.h>
#include <smmintrin.h>
#include <iostream>
using namespace std;

void max_sse(unsigned int *src, long h, long w, unsigned int *val)
{
    _STATIC_ASSERT(sizeof(unsigned int) == sizeof(BYTE)*4);
    if( w % 4 != 0)
        return; // ERROR Can't do it, need 4-multiple rows or do some alignment!
    unsigned int *aligned_src = (unsigned int*)_aligned_malloc(h*w*sizeof(unsigned int), 16); // _mm_load_si128 needs 16-bytes aligned memory
    memcpy(aligned_src, src, sizeof(unsigned int)*h*w);
    __declspec(align(16)) __m128i max = {0,0,0,0};

    // Iterates the matrix
    for(int i=0; i<h*w; i+=4)
    {
        __m128i *pg = (__m128i*)(aligned_src+i);
        __m128i PG = _mm_load_si128(pg);

        __m128i newmax = _mm_max_epu32(max, PG);
        _mm_store_si128(&max, newmax);
    }
    unsigned int abs_max = 0;
    unsigned int *max_val = (unsigned int*)&max;
    for (int i=0;i<4;i++)
    {
        if (abs_max < *(max_val+i))
        {
            abs_max = *(max_val+i);
        }
    }
    _aligned_free(aligned_src);
    cout << "The max is: " << abs_max << endl;
}


int main()
{
    unsigned int src[] = {0,1,2,4, 5,6,7,8, 224,225,226,129};
    unsigned int val;
    max_sse(src, 3,4, &val);

    return 0;
}

我认为 memcpy 是代码中必不可少的恶意,因为没有关于内存对齐的任何其他信息。如果你有什么要处理的,那就自己动手吧,它会好很多。