Оптимизировать С код
Подскажите, а можно-ли оптимизировать следующий С код (SSE, AVX).
void mtlb2opcv(uint8_t* dst, uint8_t* src, size_t sz_r, size_t sz_c)
{
uint8_t* mat_temp_ptr = NULL;
const long layer_size = sz_r*sz_c;
for (int ch = 0; ch<3; ch++)
{
mat_temp_ptr = src + ch*layer_size;
int rd = 2 - ch;
for (size_t c = 0; c < sz_c; c++)
{
for (size_t r = 0; r < sz_r; r++)
{
size_t id = (r*sz_c+c)*3+rd;
size_t is = c*sz_r+r;
dst[id] = mat_temp_ptr[is];
}
}
}
}
Это код конвертации изображения из матлаба в OpenCV формат.
Фактически изображения в матлабе лежит по слоям и в каждом слое по столбцам.
В OpenCV по строкам и цвета пикселя последовательно.
Нюанс, порядок слоев в матлабе RGB, а в OpenCV стандартно BGR.
Этот код работает в 40 раз дольше, чем последовательное копирования того же объема данных с использованием AVX.
Понятно, что граница данных выравнена.
Update:
Вот что получилось
inline void mtlb2opcv_8UC3(uint8_t * const dst, const uint8_t * const src, const size_t sz_r, const size_t sz_c)
{
const size_t layer_sz = sz_r*sz_c;
const uint8_t * layer_r = src;
const uint8_t * layer_g = layer_r + layer_sz;
const uint8_t * layer_b = layer_g + layer_sz;
const size_t n = 8;
const size_t sz_rem = sz_c/n*n;
for (size_t c = 0; c < sz_rem; c+=n)
{
for (size_t r = 0; r < sz_r; r++)
{
const size_t _id = (r*sz_c+c)*3;
for(size_t i=0; i<n; ++i)
{
const size_t id = _id+i*3;
const size_t is = (c+i)*sz_r+r;
dst[id+0] = layer_b[is];
dst[id+1] = layer_g[is];
dst[id+2] = layer_r[is];
}
}
}
for (size_t c = sz_rem; c < sz_c; c++)
{
for (size_t r = 0; r < sz_r; r++)
{
const size_t id = (r*sz_c+c)*3;
const size_t is = c*sz_r+r;
dst[id+0] = layer_b[is];
dst[id+1] = layer_g[is];
dst[id+2] = layer_r[is];
}
}
}
Это работает 15ms против того что вверху ~70 ms на FX-8320 на 1920×1080×3.И
inline void opcv2mtlb_8UC3(uint8_t * const dst, const uint8_t * const src, const size_t sz_r, const size_t sz_c)
{
const size_t layer_sz = sz_r*sz_c;
uint8_t * layer_r = dst;
uint8_t * layer_g = layer_r + layer_sz;
uint8_t * layer_b = layer_g + layer_sz;
const size_t n = 4;
const size_t sz_rem = sz_c/n*n;
for (size_t c = 0; c < sz_rem; c+=n)
{
for (size_t r = 0; r < sz_r; r++)
{
const size_t _id = (r*sz_c+c)*3;
for(size_t i=0; i<n; ++i)
{
const size_t id =_id+i*3;
const size_t is = (c+i)*sz_r+r;
layer_b[is] = src[id+0];
layer_g[is] = src[id+1];
layer_r[is] = src[id+2];
}
}
}
for (size_t c = sz_rem; c < sz_c; c++)
{
for (size_t r = 0; r < sz_r; r++)
{
const size_t id = (r*sz_c+c)*3;
const size_t is = c*sz_r+r;
layer_b[is] = src[id+0];
layer_g[is] = src[id+1];
layer_r[is] = src[id+2];
}
}
}
Это работает 30ms против того что вверху ~70 ms на FX-8320 на 1920×1080×3.

153 коментарі
Додати коментар Підписатись на коментаріВідписатись від коментарів