Оптимизировать С код
Подскажите, а можно-ли оптимизировать следующий С код (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 коментарі
Додати коментар Підписатись на коментаріВідписатись від коментарів