Сообщение перемножение ядра свертки фильтра размером 3x3 с массивом це от 17.05.2018 14:39
Изменено 22.05.2018 14:37 MartinEden
перемножение ядра свертки фильтра размером 3x3 с массивом це
Имеется сверточное ядро 3х3 и изображение, представленной массивом пикселей целочисленных значение.
Сверточное ядро представлено так:
сверточное ядро = ядро H + ядро V
Реализация на С-коде имеется, теперь пытаюсь ее переложить на SSE код.
Я правда не знаю, как делать перемножение сверточного 3x3 ядра с SSE считанной строкой.
Буду очень благодарен, если покажете.
Сверточное ядро представлено так:
//составные сверточные ядра :
//
// сверточное ядро H =
//......| 1, 0, 1|
//src x | 0, 0, 0|
//......|-1, 0, -1|
//
//
// сверточное ядро V =
//......| 1, 0, -1|
//src x | 0, 0, 0|
//......| 1, 0, -1|
//
сверточное ядро = ядро H + ядро V
Реализация на С-коде имеется, теперь пытаюсь ее переложить на SSE код.
for(int inc=0; inc<height-2; inc++)
{
//загрузил в пямять 3 строки
str1_16pxs = _mm_loadu_si128((__m128i*)(src_all_str));
str2_16pxs = _mm_loadu_si128((__m128i*)(src2_all_str));
str3_16pxs = _mm_loadu_si128((__m128i*)(src3_all_str));
//упаковал по 16 разрядов
str1_16pxs_pack1st_8to16 = _mm_cvtepu8_epi16(str1_16pxs);
str2_16pxs_pack1st_8to16 = _mm_cvtepu8_epi16(str2_16pxs);
str3_16pxs_pack1st_8to16 = _mm_cvtepu8_epi16(str3_16pxs);
//---!
//здесь делаем 1ую свертку для 8px's
//...
//---
//summ 1st 8to16 vertical registers
sum1_str12_vert_16pxs_pack1st_8to16 = _mm_add_epi16(str1_16pxs_pack1st_8to16, str2_16pxs_pack1st_8to16);
sum1_str123_vert_16pxs_pack1st_8to16 = _mm_add_epi16(sum1_str12_vert_16pxs_pack1st_8to16,str3_16pxs_pack1st_8to16);
for(int jnc=0; jnc<(width >> 4); jnc++)
{
str1_16pxs_plus_8pxs = _mm_srli_si128(str1_16pxs, 8);
str2_16pxs_plus_8pxs = _mm_srli_si128(str2_16pxs, 8);
str3_16pxs_plus_8pxs = _mm_srli_si128(str3_16pxs, 8);
//pack 2nd 8to16 registers (+8px's)
str1_16pxs_pack2nd_8to16 = _mm_cvtepu8_epi16(str1_16pxs_plus_8pxs);
str2_16pxs_pack2nd_8to16 = _mm_cvtepu8_epi16(str2_16pxs_plus_8pxs);
str3_16pxs_pack2nd_8to16 = _mm_cvtepu8_epi16(str3_16pxs_plus_8pxs);
//---!
//делаем свертку для остальных 8px's и так до конца считанной строки
//...
//---
//summ vertic 8to16 registers
sum1_str12_vert_16pxs_pack2nd_8to16 = _mm_add_epi16(str1_16pxs_pack2nd_8to16, str2_16pxs_pack2nd_8to16);
sum1_str123_vert_16pxs_pack2nd_8to16 = _mm_add_epi16(sum1_str12_vert_16pxs_pack2nd_8to16,str3_16pxs_pack2nd_8to16);
//---!4 loading next 16 px's
src_all_str += 16;
src2_all_str += 16;
src3_all_str += 16;
//...
_mm_store_si128((__m128i*)(dst_all_str), res);
dst_all_str += 8;
}//for(jnc)
}//for(inc)
Я правда не знаю, как делать перемножение сверточного 3x3 ядра с SSE считанной строкой.
Буду очень благодарен, если покажете.
перемножение ядра свертки фильтра размером 3x3 с массивом це
Имеется сверточное ядро 3х3 и изображение, представленной массивом пикселей целочисленных значение.
Сверточное ядро представлено так:
сверточное ядро = ядро H + ядро V
Реализация на С-коде имеется, теперь пытаюсь ее переложить на SSE код.
Я правда не знаю, как делать перемножение сверточного 3x3 ядра с SSE считанной строкой.
Буду очень благодарен, если покажете.
Сверточное ядро представлено так:
//составные сверточные ядра :
//
// сверточное ядро H =
//......| 1, 0, 1|
//src x | 0, 0, 0|
//......|-1, 0, -1|
//
//
// сверточное ядро V =
//......| 1, 0, -1|
//src x | 0, 0, 0|
//......| 1, 0, -1|
//
сверточное ядро = ядро H + ядро V
Реализация на С-коде имеется, теперь пытаюсь ее переложить на SSE код.
for(int inc=0; inc<height-2; inc++)
{
//загрузил в пямять 3 строки
str1_16pxs = _mm_loadu_si128((__m128i*)(src_all_str));
str2_16pxs = _mm_loadu_si128((__m128i*)(src2_all_str));
str3_16pxs = _mm_loadu_si128((__m128i*)(src3_all_str));
//упаковал по 16 разрядов
str1_16pxs_pack1st_8to16 = _mm_cvtepu8_epi16(str1_16pxs);
str2_16pxs_pack1st_8to16 = _mm_cvtepu8_epi16(str2_16pxs);
str3_16pxs_pack1st_8to16 = _mm_cvtepu8_epi16(str3_16pxs);
//---!
//здесь делаем 1ую свертку для 8px's
//... В этом месте должен вставляется код !!!!
//---
//summ 1st 8to16 vertical registers
sum1_str12_vert_16pxs_pack1st_8to16 = _mm_add_epi16(str1_16pxs_pack1st_8to16, str2_16pxs_pack1st_8to16);
sum1_str123_vert_16pxs_pack1st_8to16 = _mm_add_epi16(sum1_str12_vert_16pxs_pack1st_8to16,str3_16pxs_pack1st_8to16);
for(int jnc=0; jnc<(width >> 4); jnc++)
{
str1_16pxs_plus_8pxs = _mm_srli_si128(str1_16pxs, 8);
str2_16pxs_plus_8pxs = _mm_srli_si128(str2_16pxs, 8);
str3_16pxs_plus_8pxs = _mm_srli_si128(str3_16pxs, 8);
//pack 2nd 8to16 registers (+8px's)
str1_16pxs_pack2nd_8to16 = _mm_cvtepu8_epi16(str1_16pxs_plus_8pxs);
str2_16pxs_pack2nd_8to16 = _mm_cvtepu8_epi16(str2_16pxs_plus_8pxs);
str3_16pxs_pack2nd_8to16 = _mm_cvtepu8_epi16(str3_16pxs_plus_8pxs);
//---!
//делаем свертку для остальных 8px's и так до конца считанной строки
//... В этом месте должен вставляется код !!!!
//---
//summ vertic 8to16 registers
sum1_str12_vert_16pxs_pack2nd_8to16 = _mm_add_epi16(str1_16pxs_pack2nd_8to16, str2_16pxs_pack2nd_8to16);
sum1_str123_vert_16pxs_pack2nd_8to16 = _mm_add_epi16(sum1_str12_vert_16pxs_pack2nd_8to16,str3_16pxs_pack2nd_8to16);
//---!4 loading next 16 px's
src_all_str += 16;
src2_all_str += 16;
src3_all_str += 16;
//...
_mm_store_si128((__m128i*)(dst_all_str), res);
dst_all_str += 8;
}//for(jnc)
}//for(inc)
Я правда не знаю, как делать перемножение сверточного 3x3 ядра с SSE считанной строкой.
Буду очень благодарен, если покажете.