1) I don't see any code dealing with alignment
2) There's a mismatch between unsigned integers and _mm_max_epi8 which comapares 8-bit signed integers (http://msdn.microsoft.com/en-us/library/bb514045(v=vs.90).aspx)
3) I'm assuming you have a h*w matrix with rows multiple of 4 (or dealing with that with some padding for instance)
On Windows you could do something like:
#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;
}
I'm assuming the memcpy a necessary evil in your code since there isn't any other information on memory alignment. If you have something to deal with that, do it yourself and it will be a lot better.