рдкрд░рд┐рдЪрдп
рдЗрд╕рд╕реЗ рдкрд╣рд▓реЗ рдкрд░рд┐рдЪрдпрд╛рддреНрдордХ
рд▓реЗрдЦ рдореЗрдВ, рдореИрдВрдиреЗ рдЙрди рд╕рдорд╕реНрдпрд╛рдУрдВ рдХреА рдПрдХ рд╕реВрдЪреА рддреИрдпрд╛рд░ рдХреА, рдЬрд┐рдиреНрд╣реЗрдВ рдПрдХ рдбреЗрд╡рд▓рдкрд░ рдХреЛ рд╕рд╛рдордирд╛ рдХрд░рдирд╛ рдкрдбрд╝реЗрдЧрд╛ рдпрджрд┐ рд╡рд╣ SIMI рдирд┐рд░реНрджреЗрд╢реЛрдВ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рдЫрд╡рд┐ рдкреНрд░рд╕рдВрд╕реНрдХрд░рдг рдЕрдиреБрдХреВрд▓рди рдХрд╛ рдЕрдиреБрдХреВрд▓рди рдХрд░рдирд╛ рдЪрд╛рд╣рддрд╛ рд╣реИред рдЕрдм рд╕рдордп рдЖ рдЧрдпрд╛ рд╣реИ рдХрд┐ рдПрдХ рдареЛрд╕ рдЙрджрд╛рд╣рд░рдг рджрд┐рдпрд╛ рдЬрд╛рдП рдХрд┐ рдЙрдкрд░реЛрдХреНрдд рд╕рдорд╕реНрдпрд╛рдУрдВ рдХреЛ рдХреИрд╕реЗ рд╣рд▓ рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИред рдореИрдВрдиреЗ рдПрдХ рд▓рдВрдмреЗ рд╕рдордп рдХреЗ рд▓рд┐рдП рд╕реЛрдЪрд╛ рдерд╛ рдХрд┐ рдХреМрди рд╕рд╛ рдПрд▓реНрдЧреЛрд░рд┐рдердо рдкрд╣рд▓реЗ рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП рдЪреБрдирдирд╛ рд╣реИ, рдФрд░ рдордВрдЭрд▓рд╛ рдлрд╝рд┐рд▓реНрдЯрд░рд┐рдВрдЧ рдкрд░ рдзреНрдпрд╛рди рдХреЗрдВрджреНрд░рд┐рдд рдХрд░рдиреЗ рдХрд╛ рдирд┐рд░реНрдгрдп рд▓рд┐рдпрд╛ред рдореЗрдбрд┐рдпрди рдлрд╝рд┐рд▓реНрдЯрд░рд┐рдВрдЧ рд╢реЛрд░ рдХреЛ рджрдмрд╛рдиреЗ рдХрд╛ рдПрдХ рдкреНрд░рднрд╛рд╡реА рддрд░реАрдХрд╛ рд╣реИ рдЬреЛ рдЕрдирд┐рд╡рд╛рд░реНрдп рд░реВрдк рд╕реЗ рдХрдо рд░реЛрд╢рдиреА рд╡рд╛рд▓реЗ рджреГрд╢реНрдпреЛрдВ рдореЗрдВ рдбрд┐рдЬрд┐рдЯрд▓ рдХреИрдорд░реЛрдВ рдкрд░ рджрд┐рдЦрд╛рдИ рджреЗрддрд╛ рд╣реИред рдпрд╣ рдПрд▓реНрдЧреЛрд░рд┐рдереНрдо рдХрд╛рдлреА рд╕рдВрд╕рд╛рдзрди-рдЧрд╣рди рд╣реИ - рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рдЬрдм рдПрдХ 3x3 рдорд╛рдзреНрдп рдлрд╝рд┐рд▓реНрдЯрд░ рдХреЗ рд╕рд╛рде рдПрдХ рдЧреНрд░реЗ рдЫрд╡рд┐ рдХреЛ рд╕рдВрд╕рд╛рдзрд┐рдд рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ, рддреЛ рдкреНрд░рддрд┐ рдЫрд╡рд┐ рдмрд┐рдВрджреБ рдкрд░ рд▓рдЧрднрдЧ 50 рд╕рдВрдЪрд╛рд▓рди рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реЛрддреА рд╣реИред рд▓реЗрдХрд┐рди рдПрдХ рд╣реА рд╕рдордп рдореЗрдВ, рд╡рд╣ рдХреЗрд╡рд▓ 8-рдмрд┐рдЯ рд╕рдВрдЦреНрдпрд╛ рдХреЗ рд╕рд╛рде рдХрд╛рдо рдХрд░рддрд╛ рд╣реИ рдФрд░ рдЙрд╕реЗ рдХрд╛рдо рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдЕрдкреЗрдХреНрд╖рд╛рдХреГрдд рдХрдо рдЗрдирдкреБрдЯ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реЛрддреА рд╣реИред рдпреЗ рдкрд░рд┐рд╕реНрдерд┐рддрд┐рдпрд╛рдБ SIMD рдЕрдиреБрдХреВрд▓рди рдХреЗ рд▓рд┐рдП рдПрд▓реНрдЧреЛрд░рд┐рдереНрдо рдХреЛ рдХрд╛рдлреА рд╕рд░рд▓ рдмрдирд╛рддреА рд╣реИрдВ рдФрд░ рд╕рд╛рде рд╣реА рд╕рд╛рде рдЗрд╕рд╕реЗ рдмрд╣реБрдд рдорд╣рддреНрд╡рдкреВрд░реНрдг рддреНрд╡рд░рдг рдкреНрд░рд╛рдкреНрдд рдХрд░рдирд╛ рд╕рдВрднрд╡ рдмрдирд╛рддреА рд╣реИрдВред

рд╕рдВрджрд░реНрдн рдХреЗ рд▓рд┐рдП, рдореБрдЭреЗ рдПрд▓реНрдЧреЛрд░рд┐рдереНрдо рдХрд╛ рд╕рд╛рд░ рдпрд╛рдж рд╣реИ:
- рдореВрд▓ рдЫрд╡рд┐ рдХреЗ рдкреНрд░рддреНрдпреЗрдХ рдмрд┐рдВрджреБ рдХреЗ рд▓рд┐рдП, рдПрдХ рдирд┐рд╢реНрдЪрд┐рдд рдкрдбрд╝реЛрд╕ рд▓рд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ (рд╣рдорд╛рд░реЗ рдорд╛рдорд▓реЗ рдореЗрдВ, 3x3)ред
- рдЗрд╕ рдкрдбрд╝реЛрд╕ рдореЗрдВ рдЕрдВрдХ рдЪрдордХ рдХреЛ рдмрдврд╝рд╛рдХрд░ рд╣рд▓ рдХрд┐рдП рдЬрд╛рддреЗ рд╣реИрдВред
- рд╕реЙрд░реНрдЯ рдХрд┐рдП рдЧрдП рдкрдбрд╝реЛрд╕ рдХрд╛ рдорд┐рдбрдкреЙрдЗрдВрдЯ (рдПрдХ 3x3 рдлрд╝рд┐рд▓реНрдЯрд░ рдХреЗ рд▓рд┐рдП 5 рд╡рд╛рдВ) рдЕрдВрддрд┐рдо рдЫрд╡рд┐ рдореЗрдВ рджрд░реНрдЬ рдХрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИред
рдкрд╣рд▓реЗ рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рдореИрдВрдиреЗ рдХрд╛рд░реНрдп рдХреЛ рдЖрд╕рд╛рди рдмрдирд╛рдиреЗ рдХрд╛ рдлреИрд╕рд▓рд╛ рдХрд┐рдпрд╛ рдФрд░ рдПрдХ рдЧреНрд░реЗ рдЫрд╡рд┐ (8 рдмрд┐рдЯ рдкреНрд░рддрд┐ рдмрд┐рдВрджреБ) рдХреЗ рдорд╛рдорд▓реЗ рдкрд░ рд╡рд┐рдЪрд╛рд░ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рд╕реАрдорд╛ рдХреЗ рдкреНрд░рднрд╛рд╡реЛрдВ рдХреЛ рдзреНрдпрд╛рди рдореЗрдВ рд░рдЦреЗ рдмрд┐рдирд╛ - рдЗрд╕рдХреЗ рд▓рд┐рдП, рдереЛрдбрд╝реА рдмрдбрд╝реА рдЫрд╡рд┐ рдХреЗ рдордзреНрдп рднрд╛рдЧ рдХреЛ рдЫрд╛рдирдиреЗ рдХреЗ рд▓рд┐рдП рд▓рд┐рдпрд╛ рдЧрдпрд╛ рдерд╛ред рдмреЗрд╢рдХ, рд╡рд╛рд╕реНрддрд╡рд┐рдХ рд╕рдорд╕реНрдпрд╛рдУрдВ рдореЗрдВ, рдЫрд╡рд┐ рдХреЗ рд╕реАрдорд╛ рдмрд┐рдВрджреБрдУрдВ рдХреА рдЧрдгрдирд╛ рдПрдХ рд╡рд┐рд╢реЗрд╖ рдПрд▓реНрдЧреЛрд░рд┐рдереНрдо рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рдХреА рдЬрд╛рдиреА рдЪрд╛рд╣рд┐рдП, рдФрд░ рдХрднреА-рдХрднреА рдЗрди рд╡рд┐рд╢реЗрд╖ рдПрд▓реНрдЧреЛрд░рд┐рджрдо рдХреЗ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рдореЗрдВ рдЕрдзрд┐рдХрд╛рдВрд╢ рдХреЛрдб рд╣реЛ рд╕рдХрддреЗ рд╣реИрдВ, рд▓реЗрдХрд┐рди рд╣рдо рдЗрди рдореБрджреНрджреЛрдВ рдкрд░ рдПрдХ рдФрд░ рд╕рдордп рдХрд╛ рдзреНрдпрд╛рди рд░рдЦреЗрдВрдЧреЗред рдЗрд╕рдХреЗ рдЕрд▓рд╛рд╡рд╛, рдЗрд╕реА рддрд░рд╣ рдХреЗ рдХрд╛рд░рдгреЛрдВ рдХреЗ рд▓рд┐рдП, рдпрд╣ рдорд╛рдирд╛ рдЬрд╛рддрд╛ рд╣реИ рдХрд┐ рдЫрд╡рд┐ рдХреА рдЪреМрдбрд╝рд╛рдИ 32 рд╕реЗ рдЕрдзрд┐рдХ рд╣реИред
рдПрд▓реНрдЧреЛрд░рд┐рдереНрдо рдХреЗ рд╕реНрдХреЗрд▓рд░ рд╕рдВрд╕реНрдХрд░рдг
1 рд╕реНрдХреЗрд▓рд░ рд╕рдВрд╕реНрдХрд░рдг
рдЗрд╕ рдкреНрд░рд╛рд░рдВрднрд┐рдХ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рдореЗрдВ, рд╕рдорд╕реНрдпрд╛ рдХреЛ рд╕рд┐рд░ рдкрд░ рд╣рд▓ рдХрд┐рдпрд╛ рдЧрдпрд╛ рдерд╛: рдореВрд▓ рдЫрд╡рд┐ рдХреЗ рдкреНрд░рддреНрдпреЗрдХ рдмрд┐рдВрджреБ рдХреЗ рд▓рд┐рдП рдкрдбрд╝реЛрд╕ рдХреЛ рдПрдХ рд╕рд╣рд╛рдпрдХ рд╕рд░рдгреА рдореЗрдВ рдХреЙрдкреА рдХрд┐рдпрд╛ рдЧрдпрд╛ рдерд╛, рдЬрд┐рд╕реЗ рддрдм std :: рд╕реЙрд░реНрдЯ () рдлрд╝рдВрдХреНрд╢рди рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рд╕реЙрд░реНрдЯ рдХрд┐рдпрд╛ рдЧрдпрд╛ рдерд╛ред
inline void Load(const uint8_t * src, int a[3]) { a[0] = src[-1]; a[1] = src[0]; a[2] = src[1]; } inline void Load(const uint8_t * src, size_t stride, int a[9]) { Load(src - stride, a + 0); Load(src, a + 3); Load(src + stride, a + 6); } inline void Sort(int a[9]) { std::sort(a, a + 9); } void MedianFilter(const uint8_t * src, size_t srcStride, size_t width, size_t height, uint8_t * dst, size_t dstStride) { int a[9]; for(size_t y = 0; y < height; ++y) { for(size_t x = 0; x < width; ++x) { Load(src + x, srcStride, a); Sort(a); dst[x] = (uint8_t)a[4]; } src += srcStride; dst += dstStride; } }
рджреВрд╕рд░рд╛ рд╕реНрдХреЗрд▓рд░ рд╕рдВрд╕реНрдХрд░рдг
рдкрд┐рдЫрд▓реА рд╡рд┐рдзрд┐, рд╣рд╛рд▓рд╛рдВрдХрд┐, рддреБрд░рдВрдд рдПрдХ рдЕрдбрд╝рдЪрди рджрд┐рдЦрд╛рддреА рд╣реИ - рдпрд╣ рдорд╛рдирдХ рд╕реЙрд░реНрдЯрд┐рдВрдЧ рдлрд╝рдВрдХреНрд╢рди рд╣реИред рдпрд╣ рдордирдорд╛рдиреЗ рдЖрдХрд╛рд░ рдХреА рдПрдХ рд╕рд░рдгреА рдХреЛ рдЫрд╛рдВрдЯрдиреЗ рдХреЗ рд▓рд┐рдП рд╣реИ, рдпрд╣ рдХрдИ рдЖрдВрддрд░рд┐рдХ рдЬрд╛рдВрдЪ рдХрд░рддрд╛ рд╣реИ, рдЗрд╕рд▓рд┐рдП рдпрд╣ рд╕рдмрд╕реЗ рдЕрдзрд┐рдХ рд╕рдВрднрд╛рд╡рдирд╛ рд╣реИ рдХрд┐ рдЗрд╕ рд╕рдорд╕реНрдпрд╛ рдХрд╛ рдЗрд╖реНрдЯрддрдо рд╕рдорд╛рдзрд╛рди рдирд╣реАрдВ рд╣реЛрдЧрд╛, рдЬрд╣рд╛рдВ рд╕рд░рдгреА рдЫреЛрдЯрд╛ рд╣реИ рдФрд░ рдПрдХ рдирд┐рд╢реНрдЪрд┐рдд рдЖрдХрд╛рд░ рд╣реИред рдЗрд╕рдХреЗ рдЕрд▓рд╛рд╡рд╛, рд╕рд░рдгреА рдХреЛ рдкреВрд░реА рддрд░рд╣ рд╕реЗ рд╕реЙрд░реНрдЯ рдХрд░рдирд╛ рд╣рдорд╛рд░реЗ рд▓рд┐рдП рдмрд┐рд▓реНрдХреБрд▓ рднреА рдЖрд╡рд╢реНрдпрдХ рдирд╣реАрдВ рд╣реИ, рдпрд╣ рдкрд░реНрдпрд╛рдкреНрдд рд╣реИ рдХрд┐ рд╣рдо рдЬреЛ рдореВрд▓реНрдп рдЪрд╛рд╣рддреЗ рд╣реИрдВ рд╡рд╣ 4 рд╡реЗрдВ рддрддреНрд╡ рдореЗрдВ рд╣реИред рдЗрд╕рд▓рд┐рдП, рд╣рдо "рдиреЗрдЯрд╡рд░реНрдХ" рд╕реЙрд░реНрдЯрд┐рдВрдЧ рд╡рд┐рдзрд┐ (рдЬрд┐рд╕реЗ рдмрд┐рдЯреЛрдирд┐рдХ рд╕реЙрд░реНрдЯрд┐рдВрдЧ рд╡рд┐рдзрд┐ рдХреЗ рд░реВрдк рдореЗрдВ рднреА рдЬрд╛рдирд╛ рдЬрд╛рддрд╛ рд╣реИ) рдХреЛ рд▓рд╛рдЧреВ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ:
inline void Sort(int & a, int & b)
3 рд╕реНрдХреЗрд▓рд░ рд╕рдВрд╕реНрдХрд░рдг
рдпрджреНрдпрдкрд┐ рдкрд╣рд▓рд╛ рддрд░реАрдХрд╛ рд╢реВрдиреНрдп рд╡рд┐рдзрд┐ рдХреА рддреБрд▓рдирд╛ рдореЗрдВ рдмрд╣реБрдд рддреЗрдЬ рдирд┐рдХрд▓рд╛ (рдиреАрдЪреЗ рдкрд░реАрдХреНрд╖рдг рдкрд░рд┐рдгрд╛рдо рджреЗрдЦреЗрдВ), рдЗрд╕рдореЗрдВ рдЕрднреА рднреА рдПрдХ рдЕрдбрд╝рдЪрди рд╣реИ - рдЗрд╕ рдкрджреНрдзрддрд┐ рдореЗрдВ рдмрд╣реБрдд рдЕрдзрд┐рдХ рд╕рд╢рд░реНрдд рд╕рдВрдХреНрд░рдордг рд╣реИрдВред рдЬреИрд╕рд╛ рдХрд┐ рдЖрдк рдЬрд╛рдирддреЗ рд╣реИрдВ, рдЖрдзреБрдирд┐рдХ рдкреНрд░реЛрд╕реЗрд╕рд░ рдЙрдиреНрд╣реЗрдВ рдмрд╣реБрдд рдкрд╕рдВрдж рдирд╣реАрдВ рдХрд░рддреЗ рд╣реИрдВ, рдХреНрдпреЛрдВрдХрд┐ рдЙрдирдХреЗ рдкрд╛рд╕ рдПрдХ рдкрд╛рдЗрдкрд▓рд╛рдЗрди рд╡рд╛рд╕реНрддреБрдХрд▓рд╛ рд╣реИ рдФрд░ рдПрдХ рдШрдбрд╝реА рдЪрдХреНрд░ рдореЗрдВ рдХрдИ рдирд┐рд░реНрджреЗрд╢реЛрдВ рдХреЗ рдЕрд╕рд╛рдзрд╛рд░рдг рдирд┐рд╖реНрдкрд╛рджрди рдХреА рд╕рдВрднрд╛рд╡рдирд╛ рд╣реИред рдкрд╣рд▓реЗ рдФрд░ рджреВрд╕рд░реЗ рджреЛрдиреЛрдВ рдХреЗ рд▓рд┐рдП, рд╕рд╢рд░реНрдд рд╕рдВрдХреНрд░рдордг рдмреЗрд╣рдж рдЕрд╡рд╛рдВрдЫрдиреАрдп рд╣реИрдВ, рдХреНрдпреЛрдВрдХрд┐ рдкреНрд░реЛрд╕реЗрд╕рд░ рдХреЛ рд░реЛрдХрдирд╛ рдЪрд╛рд╣рд┐рдП рдФрд░ рдЧрдгрдирд╛ рдХреЗ рдкрд░рд┐рдгрд╛рдореЛрдВ рдХреА рдкреНрд░рддреАрдХреНрд╖рд╛ рдХрд░рдиреА рдЪрд╛рд╣рд┐рдП рддрд╛рдХрд┐ рдпрд╣ рдкрддрд╛ рд▓рдЧрд╛рдпрд╛ рдЬрд╛ рд╕рдХреЗ рдХрд┐ рдХрд╛рд░реНрдпрдХреНрд░рдо рдХреА рдХрд┐рд╕ рд╢рд╛рдЦрд╛ рдореЗрдВ рдЖрдЧреЗ рдЬрд╛рдирд╛ рдЪрд╛рд╣рд┐рдПред рд╕реМрднрд╛рдЧреНрдп рд╕реЗ, рд╕рд╢рд░реНрдд рд╢рд╛рдЦрд╛рдУрдВ рдореЗрдВ рдмрдВрдЯреА рдмрд┐рдирд╛ рджреЛ 8-рдмрд┐рдЯ рдорд╛рдиреЛрдВ рдХреЛ рдХреНрд░рдорд┐рдд рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ:
inline void Sort(int & a, int & b) { int d = a - b; int m = ~(d >> 8); b += d&m; a -= d&m; }
рдЗрди рдкреНрд░рд╛рд░рдВрднрд┐рдХ рд╕реНрдХреЗрд▓рд░ рдХреЛрдб рдЕрдиреБрдХреВрд▓рди рдХрд╛ рдкрд░рд┐рдгрд╛рдо рдордВрдЭрд▓рд╛ рдлрд┐рд▓реНрдЯрд░ рдХреЗ рдирд┐рдореНрди рд╕рдВрд╕реНрдХрд░рдг рд╣реЛрдЧрд╛:
inline void Load(const uint8_t * src, int a[3]) { a[0] = src[-1]; a[1] = src[0]; a[2] = src[1]; } inline void Load(const uint8_t * src, size_t stride, int a[9]) { Load(src - stride, a + 0); Load(src, a + 3); Load(src + stride, a + 6); } inline void Sort(int & a, int & b) { int d = a - b; int m = ~(d >> 8); b += d&m; a -= d&m; } inline void Sort(int a[9])
рдпрд╣ рд╕рдВрд╕реНрдХрд░рдг рдкрд╣рд▓реЗ рд╕реЗ рд╣реА рдХрд╛рдлреА (рдХрд╣реАрдВ-рдХрд╣реАрдВ 5-6 рдЧреБрдирд╛) рдЧрддрд┐ рдореЗрдВ рдПрд▓реНрдЧреЛрд░рд┐рдереНрдо рдХреЗ рд╣рдорд╛рд░реЗ рд╢реБрд░реБрдЖрддреА рд╕рдВрд╕реНрдХрд░рдг рдХреА рддреБрд▓рдирд╛ рдореЗрдВ рддреЗрдЬ рд╣реИред рдФрд░ рдпрд╣ рдЗрд╕ рдкрд░ рдЖрдзрд╛рд░рд┐рдд рд╣реИ рдХрд┐ рд╣рдо рдПрд▓реНрдЧреЛрд░рд┐рджрдо рдХреЗ SIMD рдЕрдиреБрдХреВрд▓рди рдХреЛ рдкреВрд░рд╛ рдХрд░реЗрдВрдЧреЗ, рд╕рд╛рде рд╣реА рд╕рд╛рде рдПрд▓реНрдЧреЛрд░рд┐рдереНрдо рдХреЗ рд╕реНрдХреЗрд▓рд░ рдФрд░ рд╡реЗрдХреНрдЯрд░ рд╕рдВрд╕реНрдХрд░рдгреЛрдВ рдХреА рдЧрддрд┐ рдХреА рддреБрд▓рдирд╛ рдХрд░реЗрдВрдЧреЗред
рдПрд▓реНрдЧреЛрд░рд┐рдереНрдо рдХрд╛ SIMD рд╕рдВрд╕реНрдХрд░рдг
SIMD рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рдорд╛рдзреНрдп рдлрд╝рд┐рд▓реНрдЯрд░рд┐рдВрдЧ рдПрд▓реНрдЧреЛрд░рд┐рдереНрдо рдХреЗ рдЕрдиреБрдХреВрд▓рди рдХрд╛ рд╡рд░реНрдгрди рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рдореИрдВ рдирд┐рд░реНрджреЗрд╢реЛрдВ рдХреЗ рджреЛ рд╕реЗрдЯ SSE2 рдФрд░ AVX2 рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░реВрдБрдЧрд╛, рдЬреЛ MMX рдПрдХреНрд╕рдЯреЗрдВрд╢рди рдХреЛ рдпрд╛рдж рдХрд░ рд░рд╣рд╛ рд╣реИ, рдЬреЛ рд╡рд░реНрддрдорд╛рди рдореЗрдВ рдкреБрд░рд╛рдирд╛ рд╣реИ рдФрд░ рдЗрд╕рдореЗрдВ рдЕрдзрд┐рдХ рдРрддрд┐рд╣рд╛рд╕рд┐рдХ рд░реБрдЪрд┐ рд╣реИред рд╕реМрднрд╛рдЧреНрдп рд╕реЗ, SIMD рдирд┐рд░реНрджреЗрд╢реЛрдВ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рдХреЛрдбрд╛рдВрддрд░рдХ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдирд╛ рдЖрд╡рд╢реНрдпрдХ рдирд╣реАрдВ рд╣реИред ред рдЕрдзрд┐рдХрд╛рдВрд╢ рдЖрдзреБрдирд┐рдХ рд╕реА ++ рдХрдВрдкрд╛рдЗрд▓рд░реЛрдВ рдореЗрдВ рдЖрдВрддрд░рд┐рдХ (рдЕрдВрддрд░реНрдирд┐рд╣рд┐рдд рдХрд╛рд░реНрдп рдЬрд┐рд╕рдХреЗ рд╕рд╛рде рдЖрдк рд╕рднреА рдкреНрд░рдХрд╛рд░ рдХреЗ рдкреНрд░реЛрд╕реЗрд╕рд░ рдПрдХреНрд╕рдЯреЗрдВрд╢рди рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ) рдХреЗ рд▓рд┐рдП рд╕рдорд░реНрдерди рд╣реИред рдЖрдВрддрд░рд┐рдХ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рдкреНрд░реЛрдЧреНрд░рд╛рдорд┐рдВрдЧ рд╡реНрдпрд╛рд╡рд╣рд╛рд░рд┐рдХ рд░реВрдк рд╕реЗ рд╢реБрджреНрдз рд╕реА рдкрд░ рдкреНрд░реЛрдЧреНрд░рд╛рдорд┐рдВрдЧ рд╕реЗ рдЕрд▓рдЧ рдирд╣реАрдВ рд╣реИред рдЖрдВрддрд░рд┐рдХ рдХрд╛рд░реНрдпреЛрдВ рдХреЛ рд╕рдВрдХрд▓рдХ рджреНрд╡рд╛рд░рд╛ рд╕реАрдзреЗ рдкреНрд░реЛрд╕реЗрд╕рд░ рдирд┐рд░реНрджреЗрд╢реЛрдВ рдореЗрдВ рдкрд░рд┐рд╡рд░реНрддрд┐рдд рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ, рд╣рд╛рд▓рд╛рдВрдХрд┐ рдкреНрд░реЛрд╕реЗрд╕рд░ рд░рдЬрд┐рд╕реНрдЯрд░реЛрдВ рдХреЗ рд╕рд╛рде рд╕реАрдзреЗ рдХрд╛рдо рдХрд░рдирд╛ рдкреНрд░реЛрдЧреНрд░рд╛рдорд░ рд╕реЗ рдЫрд┐рдкрд╛ рд░рд╣рддрд╛ рд╣реИред рдЬреНрдпрд╛рджрд╛рддрд░ рдорд╛рдорд▓реЛрдВ рдореЗрдВ, рдЗрдВрдЯреНрд░рд┐рдВрд╕рд┐рдХреНрд╕ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рд╡рд╛рд▓рд╛ рдПрдХ рдкреНрд░реЛрдЧреНрд░рд╛рдо рдЕрд╕реЗрдВрдмрд▓рд░ рдореЗрдВ рд▓рд┐рдЦреЗ рдЧрдП рдкреНрд░реЛрдЧреНрд░рд╛рдо рдХреА рдЧрддрд┐ рд╕реЗ рд╣реАрди рдирд╣реАрдВ рд╣реИред
SSE2 рд╕рдВрд╕реНрдХрд░рдг
SSE2 рдкреВрд░реНрдгрд╛рдВрдХ рдХрдорд╛рдВрдб рдХреЛ рд╣реЗрдбрд░ рдлрд╝рд╛рдЗрд▓ <emmintrin.h> рдореЗрдВ рдкрд░рд┐рднрд╛рд╖рд┐рдд рдХрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИред рдореВрд▓ рдкреНрд░рдХрд╛рд░ __m128i рд╣реИ - рдПрдХ 128 рдмрд┐рдЯ рд╡реЗрдХреНрдЯрд░, рдЬреЛ рдХрд┐ рд╕рдВрджрд░реНрдн рдХреЗ рдЖрдзрд╛рд░ рдкрд░, 2 64 рдмрд┐рдЯ, 4 32 рдмрд┐рдЯ, 8 x 16 рдмрд┐рдЯ, 16 x 8 рдмрд┐рдЯ рдкрд░ рд╣рд╕реНрддрд╛рдХреНрд╖рд░ рдХрд┐рдП рдпрд╛ рдЕрд╣рд╕реНрддрд╛рдХреНрд╖рд░рд┐рдд рд╕рдВрдЦреНрдпрд╛рдУрдВ рдХреЗ рдПрдХ рд╕реЗрдЯ рдХреЗ рд░реВрдк рдореЗрдВ рд╡реНрдпрд╛рдЦреНрдпрд╛ рдХреА рдЬрд╛ рд╕рдХрддреА рд╣реИред рдЬреИрд╕рд╛ рдХрд┐ рдЖрдк рджреЗрдЦ рд╕рдХрддреЗ рд╣реИрдВ, рд╡реЗ рди рдХреЗрд╡рд▓ рд╡реЗрдХреНрдЯрд░ рдЕрдВрдХрдЧрдгрд┐рддреАрдп рд╕рдВрдЪрд╛рд▓рди рдХрд╛ рд╕рдорд░реНрдерди рдХрд░рддреЗ рд╣реИрдВ, рдмрд▓реНрдХрд┐ рд╡реЗрдХреНрдЯрд░ рддрд╛рд░реНрдХрд┐рдХ рд╕рдВрдЪрд╛рд▓рди рднреА рдХрд░рддреЗ рд╣реИрдВ, рд╕рд╛рде рд╣реА рд╡реЗрдХреНрдЯрд░ рдбреЗрдЯрд╛ рд▓реЛрдбрд┐рдВрдЧ рдФрд░ рдЕрдирд▓реЛрдбрд┐рдВрдЧ рдСрдкрд░реЗрд╢рди рднреА рдХрд░рддреЗ рд╣реИрдВред SSE2 рдирд┐рд░реНрджреЗрд╢реЛрдВ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рдорд╛рдзреНрдпрд┐рдХрд╛ рдлрд╝рд┐рд▓реНрдЯрд░ рдХреЗ рд▓рд┐рдП рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд рдЕрдиреБрдХреВрд▓рди рд╣реИрдВред рдХреЛрдб, рдпрд╣ рдореБрдЭреЗ рд▓рдЧрддрд╛ рд╣реИ, рд╕реБрдВрджрд░ рджреГрд╢реНрдп рд╣реИред
#include < emmintrin.h > inline void Load(const uint8_t * src, __m128i a[3]) { a[0] = _mm_loadu_si128((__m128i*)(src - 1)); // 128 16 a[1] = _mm_loadu_si128((__m128i*)(src)); a[2] = _mm_loadu_si128((__m128i*)(src + 1)); } inline void Load(const uint8_t * src, size_t stride, __m128i a[9]) { Load(src - stride, a + 0); Load(src, a + 3); Load(src + stride, a + 6); } inline void Sort(__m128i& a, __m128i& b) { __m128i t = a; a = _mm_min_epu8(t, b); // 2- 8 16 b = _mm_max_epu8(t, b); // 2- 8 16 } inline void Sort(__m128i a[9]) // { Sort(a[1], a[2]); Sort(a[4], a[5]); Sort(a[7], a[8]); Sort(a[0], a[1]); Sort(a[3], a[4]); Sort(a[6], a[7]); Sort(a[1], a[2]); Sort(a[4], a[5]); Sort(a[7], a[8]); Sort(a[0], a[3]); Sort(a[5], a[8]); Sort(a[4], a[7]); Sort(a[3], a[6]); Sort(a[1], a[4]); Sort(a[2], a[5]); Sort(a[4], a[7]); Sort(a[4], a[2]); Sort(a[6], a[4]); Sort(a[4], a[2]); } void MedianFilter(const uint8_t * src, size_t srcStride, size_t width, size_t height, uint8_t * dst, size_t dstStride) { __m128i a[9]; for(size_t y = 0; y < height; ++y) { for(size_t x = 0; x < width; x += sizeof(__m128i)) { Load(src + x, srcStride, a); Sort(a); _mm_storeu_si128((__m128i*)(dst + x), a[4]); // 128 16 } src += srcStride; dst += dstStride; } }
AVX2 рд╕рдВрд╕реНрдХрд░рдг
рдкреВрд░реНрдгрд╛рдВрдХ AVX2 рдХрдорд╛рдВрдб рдХреЛ рд╣реЗрдбрд░ рдлрд╝рд╛рдЗрд▓ <immintrin.h> рдореЗрдВ рдкрд░рд┐рднрд╛рд╖рд┐рдд рдХрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИред рдореВрд▓ рдкреНрд░рдХрд╛рд░ __m256i рд╣реИ - рдПрдХ 256-рдмрд┐рдЯ рд╡реЗрдХреНрдЯрд░, рдЬреЛ рдХрд┐ рд╕рдВрджрд░реНрдн рдХреЗ рдЖрдзрд╛рд░ рдкрд░, 4 64-рдмрд┐рдЯ, 8-рдмрд┐рдЯ 32, 16-рдмрд┐рдЯ 16, 32-рдмрд┐рдЯ 8-рдмрд┐рдЯ рд╣рд╕реНрддрд╛рдХреНрд╖рд░рд┐рдд рдпрд╛ рдЕрдирд┐рд╢реНрдЪрд┐рдд рд╕рдВрдЦреНрдпрд╛рдУрдВ рдХреЗ рдПрдХ рд╕реЗрдЯ рдХреЗ рд░реВрдк рдореЗрдВ рд╡реНрдпрд╛рдЦреНрдпрд╛ рдХреА рдЬрд╛ рд╕рдХрддреА рд╣реИред рд╣рд╛рд▓рд╛рдВрдХрд┐ AVX2 рдЗрдВрд╕реНрдЯреНрд░рдХреНрд╢рди рд╕реЗрдЯ рдХрд╛рдлреА рд╣рдж рддрдХ SSE2 рдЗрдВрд╕реНрдЯреНрд░рдХреНрд╢рди рд╕реЗрдЯ (рд╡реЗрдХреНрдЯрд░ рдХреА рджреЛрдЧреБрдиреА рдЪреМрдбрд╝рд╛рдИ рдХреЛ рджреЗрдЦрддреЗ рд╣реБрдП) рдХреЛ рджреЛрд╣рд░рд╛рддрд╛ рд╣реИ, рд▓реЗрдХрд┐рди рдЗрд╕рдореЗрдВ рдХреБрдЫ рдирд┐рд░реНрджреЗрд╢ рднреА рд╣реЛрддреЗ рд╣реИрдВ рдЬрд┐рдирдХрд╛ SSE2 рдореЗрдВ рдХреЛрдИ рдПрдирд╛рд▓реЙрдЧ рдирд╣реАрдВ рд╣реИред рдиреАрдЪреЗ AVX2 рдирд┐рд░реНрджреЗрд╢реЛрдВ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рдордВрдЭрд▓рд╛ рдлрд┐рд▓реНрдЯрд░ рдХрд╛ рдЕрдиреБрдХреВрд▓рди рд╣реИред
#include < immintrin.h > inline void Load(const uint8_t * src, __m256i a[3]) { a[0] = _mm256_loadu_si256((__m128i*)(src - 1)); // 256 32 a[1] = _mm256_loadu_si256((__m128i*)(src)); a[2] = _mm256_loadu_si256((__m128i*)(src + 1)); } inline void Load(const uint8_t * src, size_t stride, __m256i a[9]) { Load(src - stride, a + 0); Load(src, a + 3); Load(src + stride, a + 6); } inline void Sort(__m256i& a, __m256i& b) { __m256i t = a; a = _mm256_min_epu8(t, b); // 2- 8 32 b = _mm256_max_epu8(t, b); // 2- 8 32 } inline void Sort(__m256i a[9]) // { Sort(a[1], a[2]); Sort(a[4], a[5]); Sort(a[7], a[8]); Sort(a[0], a[1]); Sort(a[3], a[4]); Sort(a[6], a[7]); Sort(a[1], a[2]); Sort(a[4], a[5]); Sort(a[7], a[8]); Sort(a[0], a[3]); Sort(a[5], a[8]); Sort(a[4], a[7]); Sort(a[3], a[6]); Sort(a[1], a[4]); Sort(a[2], a[5]); Sort(a[4], a[7]); Sort(a[4], a[2]); Sort(a[6], a[4]); Sort(a[4], a[2]); } void MedianFilter(const uint8_t * src, size_t srcStride, size_t width, size_t height, uint8_t * dst, size_t dstStride) { __m256i a[9]; for(size_t y = 0; y < height; ++y) { for(size_t x = 0; x < width; x += sizeof(__m256i)) { Load(src + x, srcStride, a); Sort(a); _mm256_storeu_si256((__m256i*)(dst + x), a[4]); // 256 32 } src += srcStride; dst += dstStride; } }
рдиреЛрдЯ: рдЕрдиреБрдХреВрд▓рди рд╕реЗ рдЕрдзрд┐рдХрддрдо рддреНрд╡рд░рдг рдкреНрд░рд╛рдкреНрдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, AVX2 рдирд┐рд░реНрджреЗрд╢реЛрдВ рд╡рд╛рд▓реЗ рдХреЛрдб рдХреЛ рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд рдХрдВрдкрд╛рдЗрд▓рд░ рд╡рд┐рдХрд▓реНрдкреЛрдВ рдХреЗ рд╕рд╛рде рд╕рдВрдХрд▓рд┐рдд рдХрд┐рдпрд╛ рдЬрд╛рдирд╛ рдЪрд╛рд╣рд┐рдП: (/ arch: AVX for Visual Studio 2012, -march = core-avx2 for GCC)ред рдЗрд╕рдХреЗ рдЕрд▓рд╛рд╡рд╛, рдпрд╣ рдмрд╣реБрдд рд╡рд╛рдВрдЫрдиреАрдп рд╣реИ рдХрд┐ рдХреЛрдб рдореЗрдВ рд╡реИрдХрд▓реНрдкрд┐рдХ AVX2 рдФрд░ SSE2 рдирд┐рд░реНрджреЗрд╢ рд╢рд╛рдорд┐рд▓ рдирд╣реАрдВ рд╣реИрдВ, рдХреНрдпреЛрдВрдХрд┐ рдЗрд╕ рдорд╛рдорд▓реЗ рдореЗрдВ рдкреНрд░реЛрд╕реЗрд╕рд░ рдСрдкрд░реЗрдЯрд┐рдВрдЧ рдореЛрдб рдХреЛ рд╕реНрд╡рд┐рдЪ рдХрд░рдиреЗ рд╕реЗ рд╕рдордЧреНрд░ рдкреНрд░рджрд░реНрд╢рди рдкрд░ рдкреНрд░рддрд┐рдХреВрд▓ рдкреНрд░рднрд╛рд╡ рдкрдбрд╝реЗрдЧрд╛ред рдкреВрд░реНрд╡рдЧрд╛рдореА рдХреЗ рдЖрдзрд╛рд░ рдкрд░, рдПрд▓реНрдЧреЛрд░рд┐рджрдо рдХреЗ AVX2 рдФрд░ SSE2 рд╕рдВрд╕реНрдХрд░рдгреЛрдВ рдХреЛ рдЕрд▓рдЧ-рдЕрд▓рдЧ ".cpp" рдлрд╛рдЗрд▓реЛрдВ рдореЗрдВ рд░рдЦрдиреЗ рдХреА рд╕рд▓рд╛рд╣ рджреА рдЬрд╛рддреА рд╣реИредрдкрд░реАрдХреНрд╖рдг
рдкрд░реАрдХреНрд╖рдг 2 рдПрдордмреА рдЧреНрд░реЗ рдЫрд╡рд┐рдпреЛрдВ (1920 x 1080) рдкрд░ рдХрд┐рдпрд╛ рдЧрдпрд╛ рдерд╛ред рд╕рдордп рдорд╛рдкрди рдХреА рд╕рдЯреАрдХрддрд╛ рдореЗрдВ рд╕реБрдзрд╛рд░ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рдХрдИ рдмрд╛рд░ рдкрд░реАрдХреНрд╖рдг рдЪрд▓рд╛рдП рдЧрдПред рдХреБрд▓ рдкрд░реАрдХреНрд╖рдг рдирд┐рд╖реНрдкрд╛рджрди рд╕рдордп рдХреЛ рд░рдиреЛрдВ рдХреА рд╕рдВрдЦреНрдпрд╛ рд╕реЗ рд╡рд┐рднрд╛рдЬрд┐рдд рдХрд░рдХреЗ рдирд┐рд╖реНрдкрд╛рджрди рд╕рдордп рдкреНрд░рд╛рдкреНрдд рдХрд┐рдпрд╛ рдЧрдпрд╛ рдерд╛ред рд░рдиреЛрдВ рдХреА рд╕рдВрдЦреНрдпрд╛ рдХреЛ рдЗрд╕ рддрд░рд╣ рд╕реЗ рдЪреБрдирд╛ рдЧрдпрд╛ рдерд╛ рдХрд┐ рдХреБрд▓ рдирд┐рд╖реНрдкрд╛рджрди рдХрд╛ рд╕рдордп рдХрдо рд╕реЗ рдХрдо 1 рд╕реЗрдХрдВрдб рдерд╛, рдЬреЛ рдПрд▓реНрдЧреЛрд░рд┐рджрдо рдХреЗ рдирд┐рд╖реНрдкрд╛рджрди рд╕рдордп рдХреЛ рдорд╛рдкрддреЗ рд╕рдордп рд╕рдЯреАрдХрддрд╛ рдХреЗ рджреЛ рд╕рдВрдХреЗрдд рдкреНрд░рджрд╛рди рдХрд░рдирд╛ рдЪрд╛рд╣рд┐рдПред рдПрд▓реНрдЧреЛрд░рд┐рджрдо рдХреЛ Microsoft Visual Studio 2012 рдкрд░ 64 рдмрд┐рдЯ рд╡рд┐рдВрдбреЛрдЬ 7 рдХреЗ рд▓рд┐рдП рдЕрдзрд┐рдХрддрдо рдЕрдиреБрдХреВрд▓рди рдХреЗ рд╕рд╛рде рд╕рдВрдХрд▓рд┐рдд рдХрд┐рдпрд╛ рдЧрдпрд╛ рдерд╛ рдФрд░ iCore-7 4770 рдкреНрд░реЛрд╕реЗрд╕рд░ (3.4 рдЧреАрдЧрд╛рд╣рд░реНрдЯреНрдЬ) рдкрд░ рдЪрд▓рд╛рдпрд╛ рдЧрдпрд╛ рдерд╛ред
рдирд┐рд╖реНрдкрд╛рджрди рд╕рдордп, рдПрдордПрд╕ | рд╕рд╛рдкреЗрдХреНрд╖ рддреНрд╡рд░рдг |
рд╕рдмрд╕реЗ рдЕрдЪреНрдЫрд╛ рд╕реНрдХреЗрд▓рд░ | SSE2 | AVX2 | рд╕рдмрд╕реЗ рдЕрдЪреНрдЫрд╛ рдЕрджрд┐рд╢ / SSE2 | рд╕рд░реНрд╡рд╢реНрд░реЗрд╖реНрда рд╕реНрдХреЗрд▓рд░ / AVX2 | SSE2 / AVX2 |
24,814 | 0.565 | 0.424 | 43,920 | 58,566 | 1.333 |
рдирд┐рд╖реНрдХрд░реНрд╖
рдЬреИрд╕рд╛ рдХрд┐ рдкрд░реАрдХреНрд╖рдг рдХреЗ рдкрд░рд┐рдгрд╛рдореЛрдВ рд╕реЗ рджреЗрдЦрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ, рдЖрдзреБрдирд┐рдХ рдкреНрд░реЛрд╕реЗрд╕рд░ рдкрд░ SIMD рдирд┐рд░реНрджреЗрд╢реЛрдВ рдХреЗ рдЙрдкрдпреЛрдЧ рд╕реЗ рдорд╛рдзреНрдп рдлрд╝рд┐рд▓реНрдЯрд░рд┐рдВрдЧ рдПрд▓реНрдЧреЛрд░рд┐рджрдо рдХрд╛ рддреНрд╡рд░рдг 40 рд╕реЗ 60 рдмрд╛рд░ рддрдХ рдкрд╣реБрдВрдЪ рд╕рдХрддрд╛ рд╣реИред рдпрд╣ рдореБрдЭреЗ рд▓рдЧрддрд╛ рд╣реИ рдХрд┐ рдпрд╣ рдЕрдиреБрдХреВрд▓рди рдХреЗ рд╕рд╛рде рдкрд░реЗрд╢рд╛рди рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдПрдХ рдкрд░реНрдпрд╛рдкреНрдд рд░рд╛рд╢рд┐ рд╣реИ (рдЬрдм рддрдХ рдХрд┐ рдЖрдкрдХреЗ рдХрд╛рд░реНрдпрдХреНрд░рдо рдореЗрдВ рдирд┐рд╖реНрдкрд╛рджрди рдХреА рдЧрддрд┐ рдорд╣рддреНрд╡рдкреВрд░реНрдг рдирд╣реАрдВ рд╣реИ)ред рдЗрд╕ рдкреНрд░рдХрд╛рд╢рди рдореЗрдВ рдореИрдВрдиреЗ рдпрдерд╛рд╕рдВрднрд╡ рдЙрдкрдпреЛрдЧ рдХрд┐рдП рдЧрдП рдХреЛрдб рдХреЛ рд╕рд░рд▓ рдмрдирд╛рдиреЗ рдХрд╛ рдкреНрд░рдпрд╛рд╕ рдХрд┐рдпрд╛ред
рдЗрд╕рд▓рд┐рдП, рдбреЗрдЯрд╛ рд╕рдВрд░реЗрдЦрдг, рд╕реАрдорд╛ рдмрд┐рдВрджреБрдУрдВ рдХреЗ рдкреНрд░рд╕рдВрд╕реНрдХрд░рдг, рдФрд░ рдмрд╣реБрдд рдХреБрдЫ рдЧреБрдВрдЬрд╛рдЗрд╢ рд╕реЗ рдкрд░реЗ рдмрдиреЗ рд░рд╣реЗред
рдореИрдВ рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд рд▓реЗрдЦреЛрдВ рдореЗрдВ рдЗрди рд╕рд╡рд╛рд▓реЛрдВ рдХрд╛ рдЦреБрд▓рд╛рд╕рд╛ рдХрд░рдиреЗ рдХреА рдХреЛрд╢рд┐рд╢ рдХрд░реВрдВрдЧрд╛ред рдЕрдЧрд░ рдкрд╛рдардХ рдЗрд╕ рдмрд╛рдд рдореЗрдВ рджрд┐рд▓рдЪрд╕реНрдкреА рд░рдЦрддрд╛ рд╣реИ рдХрд┐ рдЗрд╕ рдХрд╛рд░реНрдпрдХреНрд╖рдорддрд╛ рдХреЛ рд▓рд╛рдЧреВ рдХрд░рдиреЗ рд╡рд╛рд▓реЗ рдпреБрджреНрдз рдХреЗ рдХреЛрдб рдХреЛ рдХрд┐рд╕ рддрд░рд╣ рджреЗрдЦрд╛ рдЬрд╛рдПрдЧрд╛, рддреЛ рд╡рд╣ рдЗрд╕реЗ
рдпрд╣рд╛рдВ рдвреВрдВрдв рд╕рдХреЗрдЧрд╛ред