рдпрд╣ рдЗрдВрдЯреЗрд▓ рд╕реЙрдлреНрдЯрд╡реЗрдпрд░ рдиреЗрдЯрд╡рд░реНрдХ рдХреЗ рдЕрдВрдЧреНрд░реЗрдЬреА рд╕рдВрд╕реНрдХрд░рдг рдкрд░ рдореЗрд░реЗ рд╣рд╛рд▓ рдХреЗ
рдкреЛрд╕реНрдЯ рдХрд╛ рдПрдХ рдореБрдлреНрдд рдЕрдиреБрд╡рд╛рдж рд╣реИред рддреЛ рдЙрди
рдЬреЛ рд╡рд┐рдХреНрдЯреЛрд░рд┐рдпрд╛ рдЭрд┐рд╕реНрд▓рд┐рдирд╛ рдХреЛ рд╡рд┐рдХреА 13 рд╕реЗ рдЕрдзрд┐рдХ рдкрд╕рдВрдж рдХрд░рддрд╛ рд╣реИ рдЬрд┐рди рд▓реЛрдЧреЛрдВ рдиреЗ рдкрд╣рд▓реЗ рд╕реЗ рд╣реА рдЗрд╕ рдкреЛрд╕реНрдЯ рдХреЛ рджреЗрдЦрд╛ рд╣реИ, рд╡реЗ рдкрд╣рд▓реЗ рдФрд░ рдЕрдВрддрд┐рдо рдкреИрд░рд╛рдЧреНрд░рд╛рдл рдХреЛ рдкрдврд╝ рд╕рдХрддреЗ рд╣реИрдВ рдЬреЛ рдореВрд▓ рдореЗрдВ рдирд╣реАрдВ рд╣реИрдВред
- рд╕рднреА рдХреЛ рдирдорд╕реНрдХрд╛рд░, рдореБрдЭреЗ рд░реВрд╕реА рд╕реЗ C ++ рдкреНрд░реЛрдЧреНрд░рд╛рдо рдХреЛрдб рдореЗрдВ рдЕрдиреБрд╡рд╛рджрдХ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИред рдЦреИрд░, рдпрд╣реА рд╣реИ, рдореИрдВ рдПрдХ рдХрд╛рд░реНрдп рд▓рд┐рдЦ рд░рд╣рд╛ рд╣реВрдВ, рдФрд░ рдЕрдиреБрд╡рд╛рджрдХ рд╕реА ++ рдореЗрдВ рдЗрд╕рдХреЗ рд╕рдорд╛рдзрд╛рди рдХреЛ рд▓рд╛рдЧреВ рдХрд░рддрд╛ рд╣реИред рдореБрдЭреЗ рдПрдХ рдХрд╣рд╛рдВ рдорд┐рд▓ рд╕рдХрддрд╛ рд╣реИ? рдпрджрд┐ рд╕реА рдХреЗ рд▓рд┐рдП рдирд╣реАрдВ рд╣реИ, рддреЛ рд╢рд╛рдпрдж рдЕрдиреНрдп рднрд╛рд╖рд╛рдУрдВ рдХреЗ рд▓рд┐рдП рд╣реИрдВ?
- рд╣рд╛рдВ, рдЗрд╕реЗ рд╡рд┐рдХрд╛рд╕ рд╡рд┐рднрд╛рдЧ рдХрд╛ рдкреНрд░рдореБрдЦ рдХрд╣рд╛ рдЬрд╛рддрд╛ рд╣реИред рдпрджрд┐ рдЖрдк рд░реВрд╕реА рдореЗрдВ рдПрдХ рдХрд╛рд░реНрдп рд▓рд┐рдЦрддреЗ рд╣реИрдВ, рддреЛ рдЖрдк рдЗрд╕реЗ рдЕрдзреАрдирд╕реНрдереЛрдВ рдХреЛ рджреЗрддреЗ рд╣реИрдВ рдФрд░ рдпрд╣ рдХреЛрдб рддреИрдпрд╛рд░ рд╣реИ! рд╕реА рдореЗрдВ рднреА, рдбреЗрд▓реНрдлреА рдореЗрдВ рднреА, рдЬрд╛рд╡рд╛ рдореЗрдВ рднреАред рдореИрдВрдиреЗ рдЗрд╕рдХреА рдЬрд╛рдБрдЪ рдХреА!рд╡реЗ рдХрд╣рддреЗ рд╣реИрдВ рдХрд┐ рдпрд╣ рдордЬрд╛рдХ рдирд╣реАрдВ рд╣реИ, рдмрд▓реНрдХрд┐ рдкреНрд░реЛрдЧреНрд░рд╛рдорд┐рдВрдЧ рдлреЛрд░рдо рдкрд░ рдПрдХ рд╡рд╛рд╕реНрддрд╡рд┐рдХ рд╕рд╡рд╛рд▓ рд╣реИред рд╡реЗ рдпрд╣ рднреА рдХрд╣рддреЗ рд╣реИрдВ рдХрд┐ рдПрдХ рд╡реНрдпрдХреНрддрд┐ рдорд╢реАрди рдХреА рддреБрд▓рдирд╛ рдореЗрдВ рдЕрдзрд┐рдХ рдЪрд╛рд▓рд╛рдХ рд╣реИ, рдЬрд┐рд╕рдХрд╛ рдЕрд░реНрде рд╣реИ рдХрд┐ рд╡рд╣ рдЙрд╕рдХреА рдорджрдж рдХрд░ рд╕рдХрддрд╛ рд╣реИ - рдЙрд╕рдХреЗ рджрд┐рдорд╛рдЧ рдХреЛ рд╕рд╛рдЭрд╛ рдХрд░ рд╕рдХрддрд╛ рд╣реИред рд▓реЗрдХрд┐рди рдРрд╕реЗ рдХрдИ рдорд╛рдорд▓реЗ рд╣реИрдВ рдЬрдм рдпрд╣ рдирд┐рд╢реНрдЪрд┐рдд рд░реВрдк рд╕реЗ рдХрд░рдиреЗ рдпреЛрдЧреНрдп рдирд╣реАрдВ рд╣реИред рдкрд░рд┐рдгрд╛рдо рд╡рд╣реА рд╣реЛрдЧрд╛ рдЬреЛ рдЕрдкреЗрдХреНрд╖рд┐рдд рдерд╛ред
рдпрд╣рд╛рдБ рдкреНрд░рд╕рд┐рджреНрдз рдУрдкрди рд╕реЛрд░реНрд╕
OpenCV рд▓рд╛рдЗрдмреНрд░реЗрд░реА рд╕реЗ рдПрдХ рдЕрдЪреНрдЫрд╛ рдЙрджрд╛рд╣рд░рдг рд╣реИ:
cvtScale_( const Mat& srcmat, Mat& dstmat, double _scale, double _shift ) { Op op; typedef typename Op::type1 WT; typedef typename Op::rtype DT; Size size = getContinuousSize( srcmat, dstmat, srcmat.channels() ); WT scale = saturate_cast<WT>(_scale), shift = saturate_cast<WT>(_shift); for( int y = 0; y < size.height; y++ ) { const T* src = (const T*)(srcmat.data + srcmat.step*y); DT* dst = (DT*)(dstmat.data + dstmat.step*y); int x = 0; for(; x <= size.width - 4; x += 4 ) { DT t0, t1; t0 = op(src[x]*scale + shift); t1 = op(src[x+1]*scale + shift); dst[x] = t0; dst[x+1] = t1; t0 = op(src[x+2]*scale + shift); t1 = op(src[x+3]*scale + shift); dst[x+2] = t0; dst[x+3] = t1; } for( ; x < size.width; x++ ) dst[x] = op(src[x]*scale + shift); } }
рдпрд╣ рдЪрд╛рд░, рд▓рдШреБ, рдлреНрд▓реЛрдЯ рдФрд░ рдбрдмрд▓ рдХреЗ рд╕рд╛рде рдХрд╛рдо рдХрд░рдиреЗ рд╡рд╛рд▓рд╛ рдПрдХ рд╕рд░рд▓ рдЯреЗрдореНрдкрд▓реЗрдЯ рдлрд╝рдВрдХреНрд╢рди рд╣реИред
рдЗрд╕рдХреЗ рд▓реЗрдЦрдХреЛрдВ рдиреЗ рдПрд╕рдПрд╕рдИ-рд╡реЗрдХреНрдЯрд░рд╛рдЗрдЬреЗрд╢рди рдХреЗ рд╕рд╛рде рдХрдВрдкрд╛рдЗрд▓рд░ рдХреЛ 4 рдХреЗ рдЖрдВрддрд░рд┐рдХ рд▓реВрдк рдХреЛ рддреИрдирд╛рдд рдХрд░рдХреЗ рдФрд░ рд╢реЗрд╖ рдбреЗрдЯрд╛ рдкреВрдВрдЫ рдХреЛ рдЕрд▓рдЧ рд╕реЗ рд╕рдВрд╕рд╛рдзрд┐рдд рдХрд░рдиреЗ рдореЗрдВ рдорджрдж рдХрд░рдиреЗ рдХрд╛ рдирд┐рд░реНрдгрдп рд▓рд┐рдпрд╛ред
рдХреНрдпрд╛ рдЖрдкрдХреЛ рд▓рдЧрддрд╛ рд╣реИ рдХрд┐ рдЖрдзреБрдирд┐рдХ рд╕рдВрдХрд▓рдХ (рд╡рд┐рдВрдбреЛрдЬ рдХреЗ рд▓рд┐рдП) рд▓реЗрдЦрдХреЛрдВ рдХреЗ рдЗрд░рд╛рджреЗ рдХреЗ рдЕрдиреБрд╕рд╛рд░ рдЕрдиреБрдХреВрд▓рд┐рдд рдХреЛрдб рдЙрддреНрдкрдиреНрди рдХрд░реЗрдВрдЧреЗ?
рдЖрдЗрдП рдЗрд╕ рдХреЛрдб рдХреЛ рдЗрдВрдЯреЗрд▓ рдХрдВрдкрд╛рдЗрд▓рд░ 12.0 рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ / QxSSE2 рд╕реНрд╡рд┐рдЪ рдХреЗ рд╕рд╛рде рд╕рдВрдХрд▓рд┐рдд рдХрд░рдХреЗ рджреЗрдЦреЗрдВ (рдпрд╣ рд╕рддреНрдпрд╛рдкрд┐рдд рд╣реИ рдХрд┐ рдЕрдиреНрдп SSEx рдФрд░ AVX рд╡рд┐рдХрд▓реНрдкреЛрдВ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рд╕реЗ рд╕рдорд╛рди рдкрд░рд┐рдгрд╛рдо рдорд┐рд▓реЗрдЧрд╛)
рдФрд░ рдкрд░рд┐рдгрд╛рдо рдХрд╛рдлреА рдЕрдкреНрд░рддреНрдпрд╛рд╢рд┐рдд рд╣реЛрдЧрд╛ред рд╕рдВрдХрд▓рдХ рдХреЗ рдЖрдЙрдЯрдкреБрдЯ рдкрд░ рдЕрд╕реЗрдВрдмрд▓рд░ рд╕реВрдЪреА рдирд┐рд░реНрдгрд╛рдпрдХ рд░реВрдк рд╕реЗ рджрд░реНрд╢рд╛рддреА рд╣реИ рдХрд┐ рддреИрдирд╛рдд рд▓реВрдк рд╡реЗрдХреНрдЯрд░ рдирд╣реАрдВ рд╣реИред рдХрдВрдкрд╛рдЗрд▓рд░ рдПрд╕рдПрд╕рдИ рдирд┐рд░реНрджреЗрд╢ рдЙрддреНрдкрдиреНрди рдХрд░рддрд╛ рд╣реИ, рд▓реЗрдХрд┐рди рдХреЗрд╡рд▓ рд╕реНрдХреЗрд▓рд░, рд╡реЗрдХреНрдЯрд░ рдирд╣реАрдВред рд▓реЗрдХрд┐рди рдмрд╛рдХреА рдбреЗрдЯрд╛ - "рдкреВрдВрдЫ", рдЬрд┐рд╕рдореЗрдВ рдПрдХ рдЕрдирд┐рд░реНрдзрд╛рд░рд┐рдд рдЪрдХреНрд░ рдореЗрдВ рдХреЗрд╡рд▓ 1-3 рдбреЗрдЯрд╛ рддрддреНрд╡ рд╣реЛрддреЗ рд╣реИрдВ, рдХреЛ рдкреВрд░реНрдг рдХрд╛рд░реНрдпрдХреНрд░рдо рдХреЗ рдЕрдиреБрд╕рд╛рд░ рд╡реЗрдХреНрдЯрд░ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ!
рдпрджрд┐ рд╣рдо рд▓реВрдк рдХреЛ рд╣рдЯрд╛ рджреЗрдВ
for( int y = 0; y < size.height; y++ ) { const T* src = (const T*)(srcmat.data + srcmat.step*y); DT* dst = (DT*)(dstmat.data + dstmat.step*y); int x = 0; for( ; x < size.width; x++ ) dst[x] = op(src[x]*scale + shift); }
... рдФрд░ рдХреЛрдбрд╛рдВрддрд░рдХ рдХреЛ рдлрд┐рд░ рд╕реЗ рджреЗрдЦреЗрдВ (рдореИрдВрдиреЗ рдЖрдкрдХреЛ рдЗрд╕рдХреЗ рд╕рд╛рде рдирд╣реАрдВ рдбрд░рд╛рдпрд╛), рд╣рдо рдкрд╛рдПрдВрдЧреЗ рдХрд┐ рдЕрдм рдЪрдХреНрд░ рдкреВрд░реА рддрд░рд╣ рд╕реЗ рд╕рднреА рдбреЗрдЯрд╛ рдкреНрд░рдХрд╛рд░реЛрдВ рдХреЗ рд▓рд┐рдП рд╡реЗрдХреНрдЯрд░рд┐рдд рд╣реЛ рдЧрдпрд╛ рд╣реИ, рдЬреЛ рдирд┐рд╕реНрд╕рдВрджреЗрд╣ рдЙрддреНрдкрд╛рджрдХрддрд╛ рдмрдврд╝рд╛рддрд╛ рд╣реИред
рдирд┐рд╖реНрдХрд░реНрд╖ :
рдЕрдзрд┐рдХ рдХрд╛рдо - рдХрдо рдкреНрд░рджрд░реНрд╢рдиред рдХрдо рдХрд╛рдо, рдЕрдзрд┐рдХред рдРрд╕рд╛ рд╣рдореЗрд╢рд╛ рд╣реЛрддрд╛редрдзреНрдпрд╛рди рджреЗрдВ рдХрд┐ Microsoft рдХрдВрдкрд╛рдЗрд▓рд░, рд╡рд┐рдЬрд╝реБрдЕрд▓ рд╕реНрдЯреВрдбрд┐рдпреЛ 2010 рдФрд░ 2008 рдореЗрдВ / рдЖрд░реНрдЪ рдХреЗ рд╕рд╛рде: SSE2 рд╕реНрд╡рд┐рдЪ рдЙрдкрд░реЛрдХреНрдд рдХреЛрдб рдХреЛ рдпрд╛ рддреЛ рд╡рд┐рд╕реНрддрд╛рд░рд┐рдд рдпрд╛ рдзреНрд╡рд╕реНрдд рд░реВрдк рдореЗрдВ рд╕рджрд┐рд╢ рдирд╣реАрдВ рдХрд░рддрд╛ рд╣реИред рдЙрдирдХреЗ рджреНрд╡рд╛рд░рд╛ рдирд┐рд░реНрдорд┐рдд рдХреЛрдб, рджреЛрдиреЛрдВ рдорд╛рдорд▓реЛрдВ рдореЗрдВ рдЙрдкрд╕реНрдерд┐рддрд┐ рдФрд░ рдкреНрд░рджрд░реНрд╢рди рджреЛрдиреЛрдВ рдореЗрдВ рдмрд╣реБрдд рд╕рдорд╛рди рд╣реИред рдпрд╣реА рд╣реИ, рдЕрдЧрд░ рдЗрдВрдЯреЗрд▓ рдХрдВрдкрд╛рдЗрд▓рд░ рдХреЗ рд▓рд┐рдП рд▓реВрдк рдХреА рддреИрдирд╛рддреА рд╣рд╛рдирд┐рдХрд╛рд░рдХ рд╣реИ, рддреЛ рдорд╛рдЗрдХреНрд░реЛрд╕реЙрдлреНрдЯ рдХреЗ рд▓рд┐рдП рдпрд╣ рдмрд╕ рдмреЗрдХрд╛рд░ рд╣реИ :)ред
рд▓реЗрдХрд┐рди рдХреНрдпрд╛ рд╣реЛрдЧрд╛ рдпрджрд┐ рдЖрдк рдЕрднреА рднреА рд▓реВрдк рдХреА рддреИрдирд╛рддреА рдХреЛ рд╕рдВрд░рдХреНрд╖рд┐рдд рдХрд░рдирд╛ рдЪрд╛рд╣рддреЗ рд╣реИрдВ - рдХреНрдпрд╛
рдпрд╣ рдЖрдкрдХреЗ рд▓рд┐рдП рд╕реНрдореГрддрд┐ рдХреЗ рд░реВрдк рдореЗрдВ рдорд╣рдВрдЧрд╛ рд╣реИ , рд▓реЗрдХрд┐рди рд╡реЗрдХреНрдЯрд░рд╛рдЗрдЬреЗрд╢рди рднреА рдЪрд╛рд╣рддреЗ рд╣реИрдВ?
рдлрд┐рд░ рдиреАрдЪреЗ рджрд┐рдЦрд╛рдП рдЕрдиреБрд╕рд╛рд░ рдЗрдВрдЯреЗрд▓ рдХрдВрдкрд╛рдЗрд▓рд░ рдкреНрд░реИрдЧреНрдорд╕ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░реЗрдВ:
#pragma simd for(x=0; x <= size.width - 4; x += 4 ) { DT t0, t1; t0 = op(src[x]*scale + shift); t1 = op(src[x+1]*scale + shift); dst[x] = t0; dst[x+1] = t1; t0 = op(src[x+2]*scale + shift); t1 = op(src[x+3]*scale + shift); dst[x+2] = t0; dst[x+3] = t1; }
# рдкреНрд░рдкреМрддреНрд░ рдиреМрд╕рд┐рдЦрд┐рдпрд╛ for( ; x <size.width; x++ ) dst[x] = op(src[x]*scale + shift); }
рдФрд░ рдЖрдЦрд┐рд░реА рд╡рд╛рд▓рд╛ред рд╕рд╛рдЗрдХрд┐рд▓ рдХреЗ рдЕрдирд┐рдпрдВрддреНрд░рд┐рдд рд╣реЛрдиреЗ рд╕реЗ рдкреНрд░рджрд░реНрд╢рди рдкрд░ рд╕рдХрд╛рд░рд╛рддреНрдордХ рдкреНрд░рднрд╛рд╡ рдкрдбрд╝ рд╕рдХрддрд╛ рд╣реИред рд▓реЗрдХрд┐рди, рд╕рдмрд╕реЗ рдкрд╣рд▓реЗ, рд╡реИрд╢реНрд╡реАрдХрд░рдг рд╕реЗ рд╕рдВрднрд╛рд╡рд┐рдд рд▓рд╛рдн рдЕрднреА рднреА рдЗрд╕ рд╕рдХрд╛рд░рд╛рддреНрдордХ рдкреНрд░рднрд╛рд╡ рдХреЛ рдкрд╛рд░ рдХрд░ рдЬрд╛рдПрдЧрд╛, рдФрд░, рджреВрд╕рд░реЗ, рддреИрдирд╛рддреА рдХреЛ рдХрдВрдкрд╛рдЗрд▓рд░ рдХреЛ рд╕реМрдВрдкрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ, рдлрд┐рд░ рд╡реИрд╢реНрд╡реАрдХрд░рдг рдЗрд╕ рд╕реЗ рдЧреНрд░рд╕реНрдд рдирд╣реАрдВ рд╣реЛрдЧрд╛ред рдЕрдиреНрдп рдмрд╛рддреЛрдВ рдХреЗ рдЕрд▓рд╛рд╡рд╛, рдореИрдВ 27 рдЕрдХреНрдЯреВрдмрд░ рдХреЛ рдПрдХ
рд╡реЗрдмрд┐рдирд╛рд░ рдореЗрдВ рдЗрд╕ рд╡рд┐рд╖рдп рдХреЛ рдЫреВрдиреЗ рдХреА рдпреЛрдЬрдирд╛ рдмрдирд╛ рд░рд╣рд╛ рд╣реВрдВред