{"id":346316,"date":"2023-03-06T09:01:38","date_gmt":"2023-03-06T09:01:38","guid":{"rendered":"http:\/\/savepearlharbor.com\/?p=346316"},"modified":"-0001-11-30T00:00:00","modified_gmt":"-0001-11-29T21:00:00","slug":"","status":"publish","type":"post","link":"https:\/\/savepearlharbor.com\/?p=346316","title":{"rendered":"<span>Assembler \u0432 Go: \u0442\u0435\u0445\u043d\u0438\u043a\u0438 \u0443\u0441\u043a\u043e\u0440\u0435\u043d\u0438\u044f \u0438 \u043e\u043f\u0442\u0438\u043c\u0438\u0437\u0430\u0446\u0438\u0438<\/span>"},"content":{"rendered":"<div><\/div>\n<div id=\"post-content-body\">\n<div>\n<div class=\"article-formatted-body article-formatted-body article-formatted-body_version-2\">\n<div xmlns=\"http:\/\/www.w3.org\/1999\/xhtml\">\n<p>\u041f\u0440\u0438\u0432\u0435\u0442, \u0425\u0430\u0431\u0440!<\/p>\n<p>\u0412 <a href=\"https:\/\/habr.com\/ru\/post\/717716\/\" rel=\"noopener noreferrer nofollow\">\u043f\u0440\u043e\u0448\u043b\u043e\u0439 \u0441\u0442\u0430\u0442\u044c\u0435<\/a> \u044f \u0440\u0430\u0441\u0441\u043a\u0430\u0437\u044b\u0432\u0430\u043b \u043e\u0431 \u0443\u0441\u043a\u043e\u0440\u0435\u043d\u0438\u0438 \u043a\u043e\u043f\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u043e\u0432 \u043e\u0434\u043d\u043e\u0433\u043e \u0441\u043b\u0430\u0439\u0441\u0430 \u0432 \u0434\u0440\u0443\u0433\u043e\u0439 \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e \u0441\u0440\u0435\u0434\u0441\u0442\u0432 Go. \u0412 \u044d\u0442\u043e\u0442 \u0440\u0430\u0437 \u044f \u0440\u0435\u0448\u0438\u043b \u043f\u043e\u0439\u0442\u0438 \u0434\u0430\u043b\u044c\u0448\u0435 \u0438 \u043f\u043e\u0441\u043c\u043e\u0442\u0440\u0435\u0442\u044c, \u0447\u0442\u043e \u043c\u043e\u0436\u043d\u043e \u0434\u043e\u0441\u0442\u0438\u0447\u044c, \u043d\u0430\u0447\u0430\u0432 \u0440\u0430\u0437\u0433\u043e\u0432\u0430\u0440\u0438\u0432\u0430\u0442\u044c \u0441 \u043f\u0440\u043e\u0446\u0435\u0441\u0441\u043e\u0440\u043e\u043c \u043d\u0430 \u0435\u0433\u043e \u044f\u0437\u044b\u043a\u0435. \u042f \u0432\u044b\u0431\u0440\u0430\u043b \u043e\u0434\u043d\u0443 \u0438\u0437 \u043e\u043f\u0442\u0438\u043c\u0438\u0437\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u044b\u0445 \u0432\u0435\u0440\u0441\u0438\u0439 \u0444\u0443\u043d\u043a\u0446\u0438\u0438 <code>Copy<\/code> \u0432 \u043a\u0430\u0447\u0435\u0441\u0442\u0432\u0435 \u043e\u0431\u044a\u0435\u043a\u0442\u0430 \u0438\u0441\u0441\u043b\u0435\u0434\u043e\u0432\u0430\u043d\u0438\u044f \u0438\u0437 <a href=\"https:\/\/habr.com\/ru\/post\/716292\/\" rel=\"noopener noreferrer nofollow\">\u0440\u0435\u0448\u0435\u043d\u0438\u044f \u0437\u0430\u0434\u0430\u0447\u0438<\/a> VK Cup&#8217;22\/23, \u043a\u043e\u0442\u043e\u0440\u0430\u044f \u043a\u043e\u043f\u0438\u0440\u0443\u0435\u0442 \u0442\u043e\u043b\u044c\u043a\u043e \u0441\u0438\u043d\u0438\u0439 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442 RGBA \u0432 Paletted \u043a\u0430\u0440\u0442\u0438\u043d\u043a\u0443:<\/p>\n<pre><code class=\"go\">func Copy(srcRGBA, dstPaletted []uint8) { srcPtr := unsafe.Add(unsafe.Pointer(&amp;srcRGBA[0]), 2) dstPtr := unsafe.Pointer(&amp;dstPaletted[0]) for range dstPaletted { *(*uint8)(dstPtr) = *(*uint8)(srcPtr) dstPtr = unsafe.Add(dstPtr, 1) srcPtr = unsafe.Add(srcPtr, 4) } }<\/code><\/pre>\n<p>\u041d\u0438\u0436\u0435 \u044f \u0440\u0430\u0441\u0441\u043a\u0430\u0436\u0443 \u043a\u0430\u043a \u0435\u0451 \u0443\u0441\u043a\u043e\u0440\u0438\u0442\u044c \u043f\u043e\u0447\u0442\u0438 \u0432 10 \u0440\u0430\u0437.<\/p>\n<h2>Disclaimer<\/h2>\n<p>\u0421 \u0432\u0435\u0440\u043e\u044f\u0442\u043d\u043e\u0441\u0442\u044c\u044e 99.9% \u043f\u0440\u0438\u0432\u0435\u0434\u0451\u043d\u043d\u043e\u0435 \u043d\u0438\u0436\u0435 \u043d\u0438\u043a\u043e\u0433\u0434\u0430 \u043d\u0435 \u043f\u0440\u0438\u0433\u043e\u0434\u0438\u0442\u0441\u044f \u0432 \u0440\u0435\u0430\u043b\u044c\u043d\u043e\u0439 \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u043a\u0435, \u0431\u043e\u043b\u0435\u0435 \u0442\u043e\u0433\u043e, \u044f \u0430\u0431\u0441\u043e\u043b\u044e\u0442\u043d\u043e \u043d\u0435 \u0433\u0430\u0440\u0430\u043d\u0442\u0438\u0440\u0443\u044e, \u0447\u0442\u043e \u0434\u0430\u043d\u043d\u044b\u0439 \u043a\u043e\u0434 \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f 100% \u043d\u0430\u0434\u0451\u0436\u043d\u044b\u043c. \u0412\u043e\u043e\u0431\u0449\u0435 \u043f\u043e\u0441\u043b\u0435\u0434\u043d\u0438\u0439 \u0440\u0430\u0437 \u044f \u0438\u0433\u0440\u0430\u043b\u0441\u044f \u0441 \u0430\u0441\u0441\u0435\u043c\u0431\u043b\u0435\u0440\u043e\u043c \u043f\u043e\u0447\u0442\u0438 20 \u043b\u0435\u0442 \u043d\u0430\u0437\u0430\u0434 \u0438 \u0432\u0441\u0451 \u043e\u043f\u0438\u0441\u0430\u043d\u043d\u043e\u0435 \u0437\u0434\u0435\u0441\u044c \u0431\u044b\u043b\u043e \u0441\u0434\u0435\u043b\u0430\u043d\u043e \u0447\u0438\u0441\u0442\u043e \u0432 \u0438\u0441\u0441\u043b\u0435\u0434\u043e\u0432\u0430\u0442\u0435\u043b\u044c\u0441\u043a\u0438\u0445 \u0446\u0435\u043b\u044f\u0445 \u0434\u043b\u044f \u0441\u0430\u043c\u043e\u0440\u0430\u0437\u0432\u0438\u0442\u0438\u044f.<\/p>\n<h2>\u0410\u0441\u0441\u0435\u043c\u0431\u043b\u0435\u0440 \u0432 Go<\/h2>\n<p>\u0417\u043d\u0430\u043a\u043e\u043c\u0441\u0442\u0432\u043e \u0441 \u0410\u0441\u0441\u0435\u043c\u0431\u043b\u0435\u0440\u043e\u043c \u0432 Go \u044f \u043d\u0430\u0447\u0430\u043b \u0441 \u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442\u0430 &#171;<a href=\"https:\/\/go.dev\/doc\/asm\" rel=\"noopener noreferrer nofollow\">A Quick Guide to Go&#8217;s Assembler<\/a>&#171;. \u0412 \u043d\u0451\u043c \u043a\u0440\u0430\u0442\u043a\u043e \u043e\u043f\u0438\u0441\u0430\u043d\u043e \u0447\u0442\u043e \u044d\u0442\u043e \u0442\u0430\u043a\u043e\u0435 \u0438 \u043a\u0430\u043a \u043e\u043d\u043e \u0443\u0441\u0442\u0440\u043e\u0435\u043d\u043e, \u043d\u043e, \u0435\u0441\u043b\u0438 \u0447\u0435\u0441\u0442\u043d\u043e, \u0441 \u043f\u0435\u0440\u0432\u043e\u0433\u043e \u0440\u0430\u0437\u0430 \u043c\u0430\u043b\u043e \u0447\u0442\u043e \u043f\u043e\u043d\u044f\u0442\u043d\u043e, \u043a\u0440\u043e\u043c\u0435 \u0442\u043e\u0433\u043e, \u0447\u0442\u043e \u044d\u0442\u043e \u043d\u0435 \u043f\u0440\u0438\u0432\u044b\u0447\u043d\u044b\u0439 \u0430\u0441\u0441\u0435\u043c\u0431\u043b\u0435\u0440, \u0430 Plan 9 Assembler. \u041f\u043e\u044d\u0442\u043e\u043c\u0443 \u043f\u0435\u0440\u0432\u043e\u0435 \u0447\u0442\u043e \u043f\u0440\u0438\u0445\u043e\u0434\u0438\u0442 \u0432 \u0433\u043e\u043b\u043e\u0432\u0443, \u044d\u0442\u043e \u043f\u043e\u0441\u043c\u043e\u0442\u0440\u0435\u0442\u044c \u043a\u0430\u043a \u0432\u044b\u0433\u043b\u044f\u0434\u0438\u0442 \u043f\u0440\u0438\u0432\u0435\u0434\u0451\u043d\u043d\u0430\u044f \u0432\u044b\u0448\u0435 \u0444\u0443\u043d\u043a\u0446\u0438\u044f <code>Copy<\/code> \u043d\u0430 \u043d\u0451\u043c. \u041a \u0441\u0447\u0430\u0441\u0442\u044c\u044e, Go \u043f\u0440\u0435\u0434\u043e\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u0442 \u0444\u043b\u0430\u0433 \u043a\u043e\u043c\u043f\u0438\u043b\u044f\u0446\u0438\u0438 <code>-gcflags \"-S\", \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0432\u044b\u0432\u043e\u0434\u0438\u0442 \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u0443 \u0432 \u0432\u0438\u0434\u0435 \u043c\u0430\u0448\u0438\u043d\u043d\u043e\u0433\u043e \u043a\u043e\u0434\u0430<\/code>. \u0412\u0441\u044e \u0440\u0430\u0431\u043e\u0442\u0443 \u044f \u0434\u0435\u043b\u0430\u043b \u0432 *<code>_test.go<\/code> \u0444\u0430\u0439\u043b\u0435, \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u0434\u043b\u044f \u0435\u0433\u043e \u043f\u0440\u0435\u0432\u0440\u0430\u0449\u0435\u043d\u0438\u044f \u0432 \u043a\u043e\u0434 \u043d\u0430 \u0410\u0441\u0441\u0435\u043c\u0431\u043b\u0435\u0440\u0435 \u043d\u0430\u0434\u043e \u0432\u044b\u043f\u043e\u043b\u043d\u0438\u0442\u044c <code>go test -c  -gcflags \"-S -B\" .\/fastcopy<\/code>, \u0433\u0434\u0435 <code>fastcopy<\/code> &#8212;  \u0434\u0438\u0440\u0435\u043a\u0442\u043e\u0440\u0438\u044f \u0441 \u0438\u0441\u0445\u043e\u0434\u043d\u0438\u043a\u0430\u043c\u0438. \u042f \u0442\u0430\u043a\u0436\u0435 \u043e\u0442\u043a\u043b\u044e\u0447\u0438\u043b Bounds Check \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e \u0444\u043b\u0430\u0433\u0430 <code>-B<\/code>, \u0447\u0442\u043e\u0431\u044b \u0443\u043f\u0440\u043e\u0441\u0442\u0438\u0442\u044c \u043a\u043e\u0434. \u041d\u0430 \u0432\u044b\u0445\u043e\u0434\u0435 \u0431\u0443\u0434\u0435\u0442 \u0434\u043e\u0432\u043e\u043b\u044c\u043d\u043e \u043c\u043d\u043e\u0433\u043e \u0442\u0435\u043a\u0441\u0442\u0430, \u043d\u043e \u0441\u0430\u043c\u043e\u0435 \u0438\u043d\u0442\u0435\u0440\u0435\u0441\u043d\u043e\u0435, \u044d\u0442\u043e \u043a\u0430\u043a \u0432\u044b\u0433\u043b\u044f\u0434\u0438\u0442 \u0444\u0443\u043d\u043a\u0446\u0438\u044f <code>Copy<\/code>:<\/p>\n<pre><code class=\"go\">0x0000 00000     TEXT    round-3\/fastcopy.Copy(SB), NOSPLIT|ABIInternal, $0-48 0x0000 00000     MOVQ    AX, round-3\/fastcopy.srcRGBA+8(FP) 0x0005 00005     MOVQ    DI, round-3\/fastcopy.dstPaletted+32(FP) 0x000a 00010     FUNCDATA        $0, gclocals\u00b7cNGUyZq94N9QFR70tEjj5A==(SB) 0x000a 00010     FUNCDATA        $1, gclocals\u00b7J5F+7Qw7O7ve2QcWC7DpeQ==(SB) 0x000a 00010     FUNCDATA        $5, round-3\/fastcopy.Copy.arginfo1(SB) 0x000a 00010     FUNCDATA        $6, round-3\/fastcopy.Copy.argliveinfo(SB) 0x000a 00010     PCDATA  $3, $1 0x000a 00010     ADDQ    $2, AX 0x000e 00014     XORL    CX, CX 0x0010 00016     JMP     33 0x0012 00018     MOVBLZX (AX), DX 0x0015 00021     MOVB    DL, (DI) 0x0017 00023     INCQ    CX 0x001a 00026     INCQ    DI 0x001d 00029     ADDQ    $4, AX 0x0021 00033     CMPQ    SI, CX 0x0024 00036     JGT     18 0x0026 00038     RET<\/code><\/pre>\n<p>\u0421\u0442\u0440\u043e\u043a\u0430 1 &#8212; \u044d\u0442\u043e \u043e\u043f\u0438\u0441\u0430\u043d\u0438\u0435 \u0444\u0443\u043d\u043a\u0446\u0438\u0438, \u0441\u043e\u0441\u0442\u043e\u044f\u0449\u0435\u0435 \u0438\u0437 \u043d\u0430\u0437\u0432\u0430\u043d\u0438\u044f \u0444\u0443\u043d\u043a\u0446\u0438\u0438, \u0444\u043b\u0430\u0433\u043e\u0432 \u0438 \u0440\u0430\u0437\u043c\u0435\u0440\u0430 \u0441\u0442\u0435\u043a\u0430. \u0421\u0442\u0435\u043a \u0440\u0430\u0432\u0435\u043d 48 \u0431\u0430\u0439\u0442\u0430\u043c, \u0442\u0430\u043a \u043a\u0430\u043a \u0444\u0443\u043d\u043a\u0446\u0438\u044f \u043f\u043e\u043b\u0443\u0447\u0430\u0435\u0442 2 \u0441\u043b\u0430\u0439\u0441\u0430 \u0432 \u043a\u0430\u0447\u0435\u0441\u0442\u0432\u0435 \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u043e\u0432, \u0430 \u043a\u0430\u0436\u0434\u044b\u0439 \u0441\u043b\u0430\u0439\u0441 \u0441\u043e\u0441\u0442\u043e\u0438\u0442 \u0438\u0437 \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u044b \u0441 \u0442\u0440\u0435\u043c\u044f \u043f\u043e\u043b\u044f\u043c\u0438 (\u0443\u043a\u0430\u0437\u0430\u0442\u0435\u043b\u044c \u043d\u0430 \u043c\u0430\u0441\u0441\u0438\u0432 \u0441 \u0434\u0430\u043d\u043d\u044b\u043c\u0438, \u0434\u043b\u0438\u043d\u0430 \u0438 \u043a\u0430\u043f\u0430\u0441\u0438\u0442\u0438), \u043a\u0430\u0436\u0434\u043e\u0435 \u0438\u0437 \u043a\u043e\u0442\u043e\u0440\u044b\u0445 \u0440\u0430\u0432\u043d\u043e 8 \u0431\u0430\u0439\u0442. \u0412 \u0441\u0442\u0440\u043e\u043a\u0430\u0445 2 \u0438 3 \u0432 \u0440\u0435\u0433\u0438\u0441\u0442\u0440\u044b \u043f\u043e\u043c\u0435\u0449\u0430\u044e\u0442\u0441\u044f \u0438\u0445 \u0434\u043b\u0438\u043d\u044b.<\/p>\n<p>\u0421\u0442\u0440\u043e\u043a\u0438 4-8 \u0441\u043e\u043e\u0431\u0449\u0430\u044e\u0442 \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u044e \u0434\u043b\u044f Garbage Collector, \u0430 \u0434\u0430\u043b\u0435\u0435 \u0443\u0436\u0435 \u0438\u0434\u0451\u0442 \u0441\u0430\u043c\u043e \u0442\u0435\u043b\u043e \u0444\u0443\u043d\u043a\u0446\u0438\u0438.<\/p>\n<p>\u0418\u0437 \u043d\u0435\u043e\u0431\u044b\u0447\u043d\u043e\u0433\u043e \u0432 \u0433\u043b\u0430\u0437\u0430 \u0431\u0440\u043e\u0441\u0430\u0435\u0442\u0441\u044f \u043e\u0442\u0441\u0443\u0442\u0441\u0442\u0432\u0438\u0435 \u0440\u0435\u0433\u0438\u0441\u0442\u0440\u043e\u0432 <code>RAX<\/code>, <code>EAX<\/code>, &#8230;, \u0432\u0435\u0437\u0434\u0435 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f <code>AX<\/code>. \u041f\u0435\u0440\u0432\u0430\u044f \u043c\u044b\u0441\u043b\u044c \u0431\u044b\u043b\u0430: \u043f\u043e\u0447\u0435\u043c\u0443 \u0432\u0441\u0451 16 \u0431\u0438\u0442\u043d\u043e\u0435? \u041d\u0430 \u0441\u0430\u043c\u043e\u043c \u0434\u0435\u043b\u0435 \u0440\u0430\u0437\u043c\u0435\u0440 \u0440\u0435\u0433\u0438\u0441\u0442\u0440\u043e\u0432 \u0437\u0430\u0434\u0430\u0451\u0442\u0441\u044f \u043a\u043e\u043c\u0430\u043d\u0434\u043e\u0439, \u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440 <code>MOVQ $1, AX<\/code> &#8212; \u044d\u0442\u043e <code>MOVQ $1, %RAX<\/code>, \u0430 <code>MOVD $1, AX<\/code> &#8212; \u044d\u0442\u043e <code>MOVD $1, %EAX<\/code>.<\/p>\n<h2>\u041f\u0435\u0440\u0432\u0430\u044f \u0444\u0443\u043d\u043a\u0446\u0438\u044f \u043d\u0430 \u0410\u0441\u0441\u0435\u043c\u0431\u043b\u0435\u0440\u0435.<\/h2>\n<p>\u041f\u0440\u0435\u0436\u0434\u0435 \u0447\u0435\u043c \u0441\u043e\u0437\u0434\u0430\u0432\u0430\u0442\u044c \u0444\u0443\u043d\u043a\u0446\u0438\u044e \u043d\u0430 \u0410\u0441\u0441\u0435\u043c\u0431\u043b\u0435\u0440\u0435, \u0441\u043d\u0430\u0447\u0430\u043b\u0430 \u043d\u0430\u0434\u043e \u043e\u043f\u0438\u0441\u0430\u0442\u044c \u0435\u0451 \u043d\u0430 Go, \u0434\u043b\u044f \u044d\u0442\u043e\u0433\u043e \u044f \u0432 \u0444\u0430\u0439\u043b\u0435 <code>fastcopy.go<\/code> \u0440\u044f\u0434\u043e\u043c \u0441 \u0444\u0443\u043d\u043a\u0446\u0438\u0435\u0439 <code>Copy<\/code> \u0434\u043e\u0431\u0430\u0432\u0438\u043b \u0444\u0443\u043d\u043a\u0446\u0438\u044e <code>CopyAsm<\/code> \u0431\u0435\u0437 \u0442\u0435\u043b\u0430:<\/p>\n<pre><code class=\"go\">func CopyAsm(srcRGBA, dstPaletted []uint8)<\/code><\/pre>\n<p>\u0420\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044e \u043d\u0430 \u0430\u0441\u0441\u0435\u043c\u0431\u043b\u0435\u0440\u0435 \u043d\u0430\u0434\u043e \u043f\u043e\u043b\u043e\u0436\u0438\u0442\u044c \u0432 \u0444\u0430\u0439\u043b \u0441 \u0440\u0430\u0441\u0448\u0438\u0440\u0435\u043d\u0438\u0435\u043c .s, \u0432 \u043c\u043e\u0451\u043c \u0441\u043b\u0443\u0447\u0430\u0435 \u044d\u0442\u043e <code>fastcopy_amd64.s<\/code>. \u0421\u0443\u0444\u0444\u0438\u043a\u0441  <code>_amd64<\/code> \u043d\u0443\u0436\u0435\u043d \u0434\u043b\u044f \u0442\u043e\u0433\u043e, \u0447\u0442\u043e\u0431\u044b \u043d\u0435 \u0434\u0430\u0442\u044c \u0441\u043e\u0431\u0440\u0430\u0442\u044c\u0441\u044f \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044e \u043d\u0430 \u0434\u0440\u0443\u0433\u0438\u0445 \u0430\u0440\u0445\u0438\u0442\u0435\u043a\u0442\u0443\u0440\u0430\u0445, \u0432\u0435\u0434\u044c \u0434\u043b\u044f \u043d\u0438\u0445 \u043d\u0443\u0436\u043d\u0430 \u0431\u0443\u0434\u0435\u0442 \u0434\u0440\u0443\u0433\u0430\u044f \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044f. \u041f\u0435\u0440\u0432\u0430\u044f \u0432\u0435\u0440\u0441\u0438\u044f \u043f\u043e\u043b\u0443\u0447\u0438\u043b\u0430\u0441\u044c \u0442\u0430\u043a\u0430\u044f:<\/p>\n<pre><code class=\"go\">TEXT \u00b7CopyAsm(SB),$0-48                 \/\/ \u0418\u043c\u044f \u0444\u0443\u043d\u043a\u0446\u0438\u0438 \u0434\u043e\u043b\u0436\u043d\u043e \u043d\u0430\u0447\u0438\u043d\u0430\u0442\u044c\u0441\u044f \u0441 \u00b7, \u0444\u043b\u0430\u0433\u043e\u0432 \u043d\u0435\u0442, \u0440\u0430\u0437\u043c\u0435\u0440 \u0441\u0442\u0435\u043a\u0430 48 \u0431\u0430\u0439\u0442         MOVQ    srcRGBA+0(FP), AX       \/\/ \u0412 AX \u043a\u043b\u0430\u0434\u0451\u043c \u0430\u0434\u0440\u0435\u0441 \u043c\u0430\u0441\u0441\u0438\u0432\u0430 srcRGBA         ADDQ    $2, AX                  \/\/ \u0418 \u0441\u043c\u0435\u0449\u0430\u0435\u043c \u0435\u0433\u043e \u043d\u0430 2, \u0442.\u043a. \u043d\u0443\u0436\u0435\u043d \u0442\u043e\u043b\u044c\u043a\u043e \u0441\u0438\u043d\u0438\u0439 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442         MOVQ    dstPaletted+24(FP), CX  \/\/ \u0412 CX \u043a\u043b\u0430\u0434\u0451\u043c \u0430\u0434\u0440\u0435\u0441 \u043c\u0430\u0441\u0441\u0438\u0432\u0430 dstPaletted         MOVQ    CX, BX                  \/\/ \u0414\u043b\u044f \u0432\u044b\u0445\u043e\u0434\u0430 \u0438\u0437 \u0446\u0438\u043a\u043b\u0430 \u043d\u0443\u0436\u0435\u043d \u0430\u0434\u0440\u0435\u0441 \u043f\u043e\u0441\u043b\u0435\u0434\u043d\u0435\u0433\u043e \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u0430 dstPaletted         ADDQ    $512*512, BX            \/\/ \u0411\u0435\u0440\u0451\u043c \u043d\u0430\u0447\u0430\u043b\u044c\u043d\u044b\u0439 \u0430\u0434\u0440\u0435\u0441 \u0438 \u0434\u043e\u0431\u0430\u0432\u043b\u044f\u0435\u043c \u043a \u043d\u0435\u043c\u0443 512*512  LOOP:   MOVBLZX (AX), DX                \/\/ \u041a\u043e\u043f\u0438\u0440\u0443\u0435\u043c 1 \u0431\u0430\u0439\u0442 \u043f\u043e \u0430\u0434\u0440\u0435\u0441\u0443 \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0445\u0440\u0430\u043d\u0438\u0442\u0441\u044f \u0432 AX (srcRGBA) \u0432 DX         MOVB    DL, (CX)                \/\/ \u0418 \u0437\u0430\u0442\u0435\u043c \u043a\u043e\u043f\u0438\u0440\u0443\u0435\u043c \u0435\u0433\u043e \u0432 \u044f\u0447\u0435\u0439\u043a\u0443 \u043c\u0430\u0441\u0441\u0438\u0432\u0430 dstPaletted.          INCQ    CX                      \/\/ \u0423\u0432\u0435\u043b\u0438\u0447\u0438\u0432\u0430\u0435\u043c \u0430\u0434\u0440\u0435\u0441 \u0442\u043a\u0443\u0449\u0435\u0439 \u044f\u0447\u0435\u0439\u043a\u0438 dstPaletted \u043d\u0430 1         ADDQ    $4, AX                  \/\/ \u0423\u0432\u0435\u043b\u0438\u0447\u0438\u0432\u0430\u0435\u043c \u0430\u0434\u0440\u0435\u0441 \u0442\u043a\u0443\u0449\u0435\u0439 \u044f\u0447\u0435\u0439\u043a\u0438 srcRGBA \u043d\u0430 4          CMPQ    BX, CX                  \/\/ \u0415\u0441\u043b\u0438 \u043d\u0435 \u0434\u043e\u0441\u0442\u0438\u0433\u043b\u0438 \u043a\u043e\u043d\u0446\u0430         JGT     LOOP                    \/\/ \u0422\u043e \u0438\u0434\u0451\u043c \u043d\u0430 \u0441\u0442\u0440\u043e\u043a\u0443 8         RET                             \/\/ \u0418\u043d\u0430\u0447\u0435 \u0432\u044b\u0445\u043e\u0434<\/code><\/pre>\n<p>\u0412 \u0434\u0430\u043d\u043d\u043e\u0439 \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438 \u044f \u0438\u0437\u0431\u0430\u0432\u0438\u043b\u0441\u044f \u043e\u0442 \u0445\u0440\u0430\u043d\u0435\u043d\u0438\u044f \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u043e\u0439 \u0446\u0438\u043a\u043b\u0430 \u0432 \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u043e\u043c \u0440\u0435\u0433\u0438\u0441\u0442\u0440\u0435, \u0430 \u0442\u0430\u043a \u043e\u043d\u0430 \u043e\u0447\u0435\u043d\u044c \u043f\u043e\u0445\u043e\u0436\u0430 \u043d\u0430 \u0442\u043e, \u0447\u0442\u043e \u0433\u0435\u043d\u0435\u0440\u0438\u0440\u0443\u0435\u0442 Go. \u0415\u0441\u043b\u0438 \u0441\u0440\u0430\u0432\u043d\u0438\u0442\u044c \u0438\u0445 \u043f\u0440\u043e\u0438\u0437\u0432\u043e\u0434\u0438\u0442\u0435\u043b\u044c\u043d\u043e\u0441\u0442\u044c, \u0442\u043e, \u043a\u0430\u043a \u0438 \u043e\u0436\u0438\u0434\u0430\u043b\u043e\u0441\u044c, \u043e\u043d\u0438 \u043f\u0440\u0438\u043c\u0435\u0440\u043d\u043e \u043d\u0430 \u043e\u0434\u043d\u043e\u043c \u0443\u0440\u043e\u0432\u043d\u0435: <\/p>\n<pre><code>cpu: AMD Ryzen 7 5800H with Radeon Graphics          BenchmarkCopy BenchmarkCopy-16                      93292    128104 ns\/op BenchmarkCopyAsm-16                   94081    127012 ns\/op<\/code><\/pre>\n<h2>1. \u0423\u043c\u0435\u043d\u044c\u0448\u0430\u0435\u043c \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u0447\u0442\u0435\u043d\u0438\u0439 \u0438\u0437 \u043f\u0430\u043c\u044f\u0442\u0438<\/h2>\n<p>\u0412 \u0441\u0442\u0440\u043e\u043a\u0435 8 \u0444\u0443\u043d\u043a\u0446\u0438\u0438 <code>CopyAsm<\/code> \u0447\u0438\u0442\u0430\u0435\u0442\u0441\u044f \u0442\u043e\u043b\u044c\u043a\u043e 1 \u0431\u0430\u0439\u0442 \u0438\u0437 \u043f\u0430\u043c\u044f\u0442\u0438 \u0432 \u0440\u0435\u0433\u0438\u0441\u0442\u0440 \u0438\u043c\u0435\u044e\u0449\u0438\u0439 \u0440\u0430\u0437\u043c\u0435\u0440 8 \u0431\u0430\u0439\u0442. \u041f\u0435\u0440\u0432\u043e\u0435 \u0447\u0442\u043e \u043f\u0440\u0438\u0445\u043e\u0434\u0438\u0442 \u0432 \u0433\u043e\u043b\u043e\u0432\u0443, \u0430 \u043d\u0435 \u043f\u0440\u043e\u0447\u0438\u0442\u0430\u0442\u044c \u043b\u0438 \u0437\u0430 \u0440\u0430\u0437 \u0432\u0441\u0435 8 \u0431\u0430\u0439\u0442, \u0430 \u0434\u0430\u043b\u044c\u0448\u0435 \u0443\u0436\u0435 \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e SHRQ \u0434\u043e\u0441\u0442\u0430\u0442\u044c \u0432\u0442\u043e\u0440\u043e\u0439 \u044d\u043b\u0435\u043c\u0435\u043d\u0442:<\/p>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/579\/609\/018\/5796090181efcb7a454ab764b4699f87.png\" width=\"1939\" height=\"515\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/579\/609\/018\/5796090181efcb7a454ab764b4699f87.png\"\/><\/figure>\n<p>\u041a\u043e\u0434 \u043f\u043e\u043b\u0443\u0447\u0438\u043b\u0441\u044f \u0442\u0430\u043a\u0438\u043c:<\/p>\n<pre><code class=\"go\">TEXT \u00b7CopyAsm1R2W(SB),$0-48         MOVQ    srcRGBA+0(FP), AX         ADDQ    $2, AX         MOVQ    dstPaletted+24(FP), CX         MOVQ    CX, BX         ADDQ    $512*512, BX  LOOP:         MOVQ (AX), DX      \/\/ \u041a\u043e\u043f\u0438\u0440\u0443\u0435\u043c 8 \u0431\u0430\u0439\u0442 \u0432 DX         MOVB    DL, (CX)   \/\/ \u0421\u043e\u0445\u0440\u0430\u043d\u044f\u0435\u043c \u043f\u0435\u0440\u0432\u044b\u0439 \u0441\u0438\u043d\u0438\u0439 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442         SHRQ    $32, DX    \/\/ \u0421\u043c\u0435\u0449\u0430\u0435\u043c \u043d\u0430 4 \u0431\u0430\u0439\u0442\u0430         MOVB    DL, 1(CX)  \/\/ \u0421\u043e\u0445\u0440\u0430\u043d\u044f\u0435\u043c \u0432\u0442\u043e\u0440\u043e\u0439 \u0441\u0438\u043d\u0438\u0439 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442          ADDQ    $2, CX     \/\/ \u0410\u0434\u0440\u0435\u0441 \u043f\u043e\u043b\u0443\u0447\u0430\u0442\u0435\u043b\u044f \u0441\u043c\u0435\u0449\u0430\u0435\u043c \u0443\u0436\u0435 \u043d\u0430 2, \u0442.\u043a. \u0441\u043e\u0445\u0440\u0430\u043d\u0438\u043b\u0438 2 \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u0430         ADDQ    $8, AX     \/\/ \u0410 \u0430\u0434\u0440\u0435\u0441 \u0438\u0441\u0442\u043e\u0447\u043d\u0438\u043a\u0430 \u043d\u0430 \u043f\u0440\u043e\u0447\u0438\u0442\u0430\u043d\u043d\u044b\u0435 \u0437\u0430 \u0440\u0430\u0437 8 \u0431\u0430\u0439\u0442          CMPQ    BX, CX         JGT     LOOP         RET<\/code><\/pre>\n<p>\u0421 \u0442\u043e\u0447\u043a\u0438 \u0437\u0440\u0435\u043d\u0438\u044f \u043f\u0440\u043e\u0438\u0437\u0432\u043e\u0434\u0438\u0442\u0435\u043b\u044c\u043d\u043e\u0441\u0442\u0438 \u0432\u0441\u0451 \u0441\u0442\u0430\u043b\u043e \u0441\u0438\u043b\u044c\u043d\u043e \u043b\u0443\u0447\u0448\u0435:<\/p>\n<pre><code>cpu: AMD Ryzen 7 5800H with Radeon Graphics          BenchmarkCopy BenchmarkCopy-16                      93292    128104 ns\/op BenchmarkCopyAsm-16                   94081    127012 ns\/op BenchmarkCopyAsm1R2W-16              185229     64904 ns\/op<\/code><\/pre>\n<p>\u0410 \u0435\u0441\u043b\u0438 \u0435\u0449\u0451 \u0440\u0430\u0437\u0432\u0435\u0440\u043d\u0443\u0442\u044c \u0446\u0438\u043a\u043b, \u0442\u043e \u043c\u043e\u0436\u043d\u043e \u0434\u043e\u0431\u0438\u0442\u044c\u0441\u044f \u0435\u0449\u0451 \u0431\u043e\u043b\u044c\u0448\u0435\u0439 \u043f\u0440\u043e\u0438\u0437\u0432\u043e\u0434\u0438\u0442\u0435\u043b\u044c\u043d\u043e\u0441\u0442\u0438:<\/p>\n<pre><code>cpu: AMD Ryzen 7 5800H with Radeon Graphics          BenchmarkCopy BenchmarkCopy-16                      93292    128104 ns\/op BenchmarkCopyAsm-16                   94081    127012 ns\/op BenchmarkCopyAsm1R2W-16              185229     64904 ns\/op BenchmarkCopyAsm1R2WUnrolled-16      240812     49406 ns\/op<\/code><\/pre>\n<pre><code class=\"go\">TEXT \u00b7CopyAsm1R2WUnrolled(SB),$0-48         MOVQ    srcRGBA+0(FP), AX         ADDQ    $2, AX         MOVQ    dstPaletted+24(FP), CX         MOVQ    CX, BX         ADDQ    $512*512, BX  LOOP:         \/\/ 1         MOVQ    (AX), DX         MOVB    DL, (CX)         SHRQ    $32, DX         MOVB    DL, 1(CX)          \/\/ 2         MOVQ    8(AX), DX         MOVB    DL, 2(CX)         SHRQ    $32, DX         MOVB    DL, 3(CX)          ADDQ    $16, AX         ADDQ    $4, CX          CMPQ    BX, CX         JGT     LOOP         RET<\/code><\/pre>\n<p>\u0423\u0432\u0435\u043b\u0438\u0447\u0435\u043d\u0438\u0435 \u0440\u0430\u0437\u0432\u0451\u0440\u0442\u043a\u0438 \u043f\u0440\u043e\u0444\u0438\u0442\u0430 \u043d\u0435 \u0434\u0430\u043b\u043e, \u043f\u043e \u043a\u0440\u0430\u0439\u043d\u0435\u0439 \u043c\u0435\u0440\u0435 \u043d\u0430 \u043c\u043e\u0451\u043c CPU.<\/p>\n<h2>2. \u0423\u043c\u0435\u043d\u044c\u0448\u0430\u0435\u043c \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u0437\u0430\u043f\u0438\u0441\u0435\u0439 \u0432 \u043f\u0430\u043c\u044f\u0442\u044c<\/h2>\n<p>\u0410\u043d\u0430\u043b\u0438\u0437\u0438\u0440\u0443\u044f \u043a\u043e\u0434, \u043f\u043e\u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u0436\u0435\u043b\u0430\u043d\u0438\u0435 \u0438\u0437\u0431\u0430\u0432\u0438\u0442\u044c\u0441\u044f \u043e\u0442 \u0434\u0432\u0443\u0445 <code>MOVB DL, (CX)<\/code> \u0438 \u043f\u0440\u0435\u0432\u0440\u0430\u0442\u0438\u0442\u044c \u0438\u0445 \u0432 \u043e\u0434\u0438\u043d <code>MOVW BX, (CX)<\/code>, \u0433\u0434\u0435 \u0440\u0435\u0433\u0438\u0441\u0442\u0440 <code>BX<\/code> \u0431\u0443\u0434\u0435\u0442 \u0445\u0440\u0430\u043d\u0438\u0442\u044c 2 \u0431\u0430\u0439\u0442\u0430:<\/p>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/9e0\/55f\/eeb\/9e055feeb3ddbd78281efe0a455310a1.png\" width=\"1635\" height=\"611\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/9e0\/55f\/eeb\/9e055feeb3ddbd78281efe0a455310a1.png\"\/><\/figure>\n<pre><code class=\"go\">TEXT \u00b7CopyAsmAcc2(SB),$0-48         MOVQ    srcRGBA+0(FP), AX         ADDQ    $2, AX         MOVQ    dstPaletted+24(FP), CX         MOVQ    CX, DI         ADDQ    $512*512, DI  LOOP:   MOVQ    (AX), DX   \/\/ \u041a\u043e\u043f\u0438\u0440\u0443\u0435\u043c 8 \u0431\u0430\u0439\u0442 \u0432 DX         MOVB    DL, BL     \/\/ \u0421\u043e\u0445\u0440\u0430\u043d\u044f\u0435\u043c \u043f\u0435\u0440\u0432\u044b\u0439 \u0441\u0438\u043d\u0438\u0439 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442 \u0432 BL         SHRQ    $32, DX    \/\/ \u0421\u043c\u0435\u0449\u0430\u0435\u043c \u043d\u0430 4 \u0431\u0430\u0439\u0442\u0430         MOVB    DL, BH     \/\/ \u0421\u043e\u0445\u0440\u0430\u043d\u044f\u0435\u043c \u0432\u0442\u043e\u0440\u043e\u0439 \u0441\u0438\u043d\u0438\u0439 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442 \u0432 BH          MOVW    BX, (CX)   \/\/ \u041a\u043e\u043f\u0438\u0440\u0443\u0435\u043c 2 \u0431\u0430\u0439\u0442\u0430 \u0432 dstPaletted          ADDQ    $2, CX         ADDQ    $8, AX          CMPQ    DI, CX         JGT     LOOP         RET<\/code><\/pre>\n<p>\u0418 \u0442\u0443\u0442 \u043c\u0435\u043d\u044f \u0436\u0434\u0430\u043b \u0441\u044e\u0440\u043f\u0440\u0438\u0437, \u044d\u0442\u043e\u0442 \u0432\u0430\u0440\u0438\u0430\u043d\u0442 \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442 \u0441\u0438\u043b\u044c\u043d\u043e \u043c\u0435\u0434\u043b\u0435\u043d\u043d\u0435\u0435 \u043f\u0440\u0435\u0434\u044b\u0434\u0443\u0449\u0435\u0433\u043e:<\/p>\n<pre><code>cpu: AMD Ryzen 7 5800H with Radeon Graphics          BenchmarkCopy BenchmarkCopy-16                      93292    128104 ns\/op BenchmarkCopyAsm-16                   94081    127012 ns\/op BenchmarkCopyAsm1R2W-16              185229     64904 ns\/op BenchmarkCopyAsm1R2WUnrolled-16      240812     49406 ns\/op BenchmarkCopyAsmAcc2-16              155895     76325 ns\/op<\/code><\/pre>\n<p>\u041f\u0440\u0438\u0447\u0451\u043c \u044f \u0441\u043b\u0443\u0447\u0430\u0439\u043d\u043e \u0437\u0430\u043c\u0435\u0442\u0438\u043b, \u0447\u0442\u043e \u0435\u0441\u043b\u0438 \u043d\u0430 \u043f\u0435\u0440\u0432\u043e\u043c \u0448\u0430\u0433\u0435 \u0446\u0438\u043a\u043b\u0430 \u0434\u0435\u043b\u0430\u0442\u044c <code>XORQ BX, BX<\/code>, \u0442\u043e \u0432\u0440\u0435\u043c\u044f \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u044f \u043d\u0435\u043c\u043d\u043e\u0433\u043e \u0443\u043c\u0435\u043d\u044c\u0448\u0430\u0435\u0442\u0441\u044f. \u041d\u043e \u044d\u0442\u043e \u0443\u0436\u0435 \u0448\u0430\u043c\u0430\u043d\u0441\u0442\u0432\u043e.<\/p>\n<p>\u0421\u043b\u0435\u0434\u0443\u044e\u0449\u0430\u044f \u043f\u043e\u043f\u044b\u0442\u043a\u0430 \u0431\u044b\u043b\u0430 \u0441\u043e\u0431\u0440\u0430\u0442\u044c \u0432 \u0440\u0435\u0433\u0438\u0441\u0442\u0440\u0435 BX \u0441\u0440\u0430\u0437\u0443 8 \u0431\u0430\u0439\u0442 \u0438 \u0442\u043e\u043b\u044c\u043a\u043e \u043f\u043e\u0441\u043b\u0435 \u044d\u0442\u043e\u0433\u043e \u0438\u0445 \u0437\u0430\u043f\u0438\u0441\u0430\u0442\u044c \u0432 \u043f\u0430\u043c\u044f\u0442\u044c:<\/p>\n<pre><code class=\"go\">TEXT \u00b7CopyAsmAcc8(SB),$0-48         MOVQ    srcRGBA+0(FP), AX         ADDQ    $2, AX         MOVQ    dstPaletted+24(FP), CX         MOVQ    CX, DI         ADDQ    $512*512, DI  LOOP:   XORQ    BX, BX         MOVQ    (AX), DX         MOVB    DL, BL         SHLQ    $8, BX         SHRQ    $32, DX         MOVB    DL, BL          MOVQ    8(AX), DX         SHLQ    $8, BX         MOVB    DL, BL         SHLQ    $8, BX         SHRQ    $32, DX         MOVB    DL, BL          MOVQ    16(AX), DX         SHLQ    $8, BX         MOVB    DL, BL         SHLQ    $8, BX         SHRQ    $32, DX         MOVB    DL, BL          MOVQ    24(AX), DX         SHLQ    $8, BX         MOVB    DL, BL         SHLQ    $8, BX         SHRQ    $32, DX         MOVB    DL, BL          BSWAPQ  BX           \/\/ \u0411\u0430\u0439\u0442\u044b \u043f\u043e\u043b\u0443\u0447\u0438\u043b\u0438\u0441\u044c \u0432 \u043e\u0431\u0440\u0430\u0442\u043d\u043e\u043c \u043f\u043e\u0440\u044f\u0434\u043a\u0435, \u043f\u043e\u0436\u0442\u043e\u043c\u0443 \u043f\u0435\u0440\u0435\u0432\u043e\u0440\u0430\u0447\u0438\u0432\u0430\u0435\u043c         MOVQ    BX, (CX)     \/\/ \u0417\u0430\u043f\u0438\u0441\u044b\u0432\u0430\u0435\u043c 8 \u0431\u0430\u0439\u0442 \u0432 dstPaletted          ADDQ    $32, AX         ADDQ    $8, CX          CMPQ    DI, CX         JGT     LOOP         RET<\/code><\/pre>\n<p>\u042d\u0442\u043e\u0442 \u0432\u0430\u0440\u0438\u0430\u043d\u0442 \u043f\u043e\u0431\u0435\u0434\u0438\u043b <code>CopyAsm1R2W<\/code>, \u043d\u043e \u0432 Unrolled \u0432\u0435\u0440\u0441\u0438\u0438 \u043d\u0435\u043c\u043d\u043e\u0433\u043e \u043f\u0440\u043e\u0438\u0433\u0440\u0430\u043b:<\/p>\n<pre><code>cpu: AMD Ryzen 7 5800H with Radeon Graphics          BenchmarkCopy BenchmarkCopy-16                      93292    128104 ns\/op BenchmarkCopyAsm-16                   94081    127012 ns\/op BenchmarkCopyAsm1R2W-16              185229     64904 ns\/op BenchmarkCopyAsm1R2WUnrolled-16      240812     49406 ns\/op BenchmarkCopyAsmAcc2-16              155895     76325 ns\/op BenchmarkCopyAcc8-16                 203373     57072 ns\/op BenchmarkCopyAcc8Unrolled-16         218060     51953 ns\/op<\/code><\/pre>\n<h2>SIMD<\/h2>\n<p>\u0412\u0441\u0435 \u043f\u0440\u0435\u0434\u044b\u0434\u0443\u0449\u0438\u0435 \u043f\u043e\u043f\u044b\u0442\u043a\u0438 \u0443\u043f\u0438\u0440\u0430\u043b\u0438\u0441\u044c \u0432 \u0442\u043e, \u0447\u0442\u043e \u043a\u043e\u043c\u0430\u043d\u0434\u044b \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u044e\u0442\u0441\u044f \u043f\u043e\u0441\u043b\u0435\u0434\u043e\u0432\u0430\u0442\u0435\u043b\u044c\u043d\u043e, \u043d\u0443 \u043f\u043e\u0447\u0442\u0438 \u0432\u0441\u0435, \u0430 \u0445\u043e\u0447\u0435\u0442\u0441\u044f \u043e\u0431\u0440\u0430\u0431\u0430\u0442\u044b\u0432\u0430\u0442\u044c \u0434\u0430\u043d\u043d\u044b\u0435 \u0431\u043b\u043e\u043a\u0430\u043c\u0438. \u0414\u043b\u044f \u044d\u0442\u043e\u0433\u043e \u0432 CPU \u0435\u0441\u0442\u044c \u0432\u0435\u043a\u0442\u043e\u0440\u043d\u044b\u0435 \u0438\u043d\u0441\u0442\u0440\u0443\u043a\u0446\u0438\u0438. \u0414\u043b\u044f C++ \u0435\u0441\u0442\u044c Intrinsics, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0438\u0445 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044e\u0442, \u0432 \u043d\u0430\u0448\u0435\u043c \u0441\u043b\u0443\u0447\u0430\u0435 \u043f\u0440\u0438\u0434\u0451\u0442\u0441\u044f \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0438\u043d\u0441\u0442\u0440\u0443\u043a\u0446\u0438\u0438 \u043d\u0430\u043f\u0440\u044f\u043c\u0443\u044e. \u041a \u0441\u0447\u0430\u0441\u0442\u044c\u044e \u043d\u0430 \u043c\u043e\u0435\u0439 \u043b\u044e\u0431\u0438\u043c\u043e\u0439 <a href=\"https:\/\/www.intel.com\/content\/www\/us\/en\/docs\/intrinsics-guide\/index.html\" rel=\"noopener noreferrer nofollow\">\u0441\u0442\u0440\u0430\u043d\u0438\u0446\u0435<\/a> \u043f\u0440\u043e Intrinsics \u0435\u0441\u0442\u044c \u043e\u043f\u0438\u0441\u0430\u043d\u0438\u0435 \u0430\u0441\u0441\u0435\u043c\u0431\u043b\u0435\u0440\u043d\u044b\u0445 \u043a\u043e\u043c\u0430\u043d\u0434. \u041d\u0430\u043f\u0440\u0438\u043c\u0435\u0440<\/p>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/8d4\/18d\/e87\/8d418de8781e0a230ba85afb1c403baf.png\" width=\"992\" height=\"529\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/8d4\/18d\/e87\/8d418de8781e0a230ba85afb1c403baf.png\"\/><\/figure>\n<p>\u0412\u043e\u043e\u0431\u0449\u0435 \u0435\u0441\u0442\u044c \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u043f\u043e\u043a\u043e\u043b\u0435\u043d\u0438\u0439 \u0432\u0435\u043a\u0442\u043e\u0440\u043d\u044b\u0445 \u0438\u043d\u0441\u0442\u0440\u0443\u043a\u0446\u0438\u0439, \u043d\u0430\u0447\u0438\u043d\u0430\u044f \u043e\u0442 \u0441\u043e\u0432\u0441\u0435\u043c \u0441\u0442\u0430\u0440\u044b\u0445 \u0442\u0438\u043f\u0430 SSE, MMX, \u0434\u043e \u0441\u043e\u0432\u0440\u0435\u043c\u0435\u043d\u043d\u044b\u0445 &#8212; \u0442\u0438\u043f\u0430 AVX\/AVX2 \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u044e\u0449\u0438\u0445 \u0440\u0430\u0431\u043e\u0442\u0430\u0442\u044c \u0441 \u0440\u0435\u0433\u0438\u0441\u0442\u0440\u0430\u043c\u0438 \u0440\u0430\u0437\u043c\u0435\u0440\u043e\u043c 256 \u0431\u0438\u0442. \u0418\u043b\u0438 \u0434\u0430\u0436\u0435 AVX-512, \u043d\u043e \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u043a\u0430 \u044d\u0442\u0438\u0445 \u0438\u043d\u0441\u0442\u0440\u0443\u043a\u0446\u0438\u0439 \u043c\u0430\u043b\u043e \u0433\u0434\u0435 \u0435\u0441\u0442\u044c. \u041c\u043e\u0439 AMD Ryzen \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u0438\u0432\u0430\u0435\u0442 \u0438\u043d\u0441\u0442\u0440\u0443\u043a\u0446\u0438\u0438 AVX2, \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u0431\u0443\u0434\u0443 \u0440\u0430\u0431\u043e\u0442\u0430\u0442\u044c \u0441 \u043d\u0438\u043c\u0438.<\/p>\n<p><strong>\u0418\u0434\u0435\u044f<\/strong>: \u043a\u043e\u043f\u0438\u0440\u0443\u0435\u043c 32 \u0431\u0430\u0439\u0442\u0430 \u0438\u0437 \u043f\u0430\u043c\u044f\u0442\u0438 \u0432 AVX \u0440\u0435\u0433\u0438\u0441\u0442\u0440, \u0430 \u0438\u0445 \u043d\u0430\u043c \u0434\u043e\u0441\u0442\u0443\u043f\u043d\u043e 16 \u0448\u0442\u0443\u043a (Y0-Y15), \u043f\u0435\u0440\u0435\u043c\u0435\u0449\u0430\u0435\u043c \u0437\u0430 1 \u043a\u043e\u043c\u0430\u043d\u0434\u0443 \u0432 \u043d\u0443\u0436\u043d\u044b\u0435 \u043f\u043e\u0437\u0438\u0446\u0438\u0438 8 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442 \u0441\u0438\u043d\u0435\u0433\u043e \u0438 \u0437\u0430\u043f\u0438\u0441\u044b\u0432\u0430\u0435\u043c \u0438\u0445 \u0432 \u043f\u0430\u043c\u044f\u0442\u044c. \u041d\u043e, \u043a \u0441\u043e\u0436\u0430\u043b\u0435\u043d\u0438\u044e, \u043d\u0435\u0442 \u0442\u0430\u043a\u043e\u0439 \u043a\u043e\u043c\u0430\u043d\u0434\u044b, \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e \u043a\u043e\u0442\u043e\u0440\u043e\u0439 \u043c\u043e\u0436\u043d\u043e \u043f\u0435\u0440\u0435\u043c\u0435\u0441\u0442\u0438\u0442\u044c \u043a\u0430\u0436\u0434\u044b\u0439 \u0447\u0435\u0442\u0432\u0451\u0440\u0442\u044b\u0439 \u0431\u0430\u0439\u0442 \u0432 \u043f\u0435\u0440\u0432\u044b\u0435 8 \u0431\u0430\u0439\u0442, \u043d\u043e \u0435\u0441\u0442\u044c \u0437\u0430\u043c\u0435\u0447\u0430\u0442\u0435\u043b\u044c\u043d\u0430\u044f \u043a\u043e\u043c\u0430\u043d\u0434\u0430 <code>_mm256_shuffle_epi8<\/code>, \u043a\u043e\u0442\u043e\u0440\u0430\u044f \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u0435\u0442 \u043f\u0435\u0440\u0435\u043c\u0435\u0441\u0442\u0438\u0442\u044c 4 \u043d\u0443\u0436\u043d\u044b\u0445 \u0431\u0430\u0439\u0442\u0430 \u0432 \u043f\u0435\u0440\u0432\u044b\u0445 16\u0442\u0438, \u0438 4 &#8212; \u0432\u043e \u0432\u0442\u043e\u0440\u044b\u0445 16. \u0415\u0441\u043b\u0438 \u043f\u0440\u043e\u0447\u0438\u0442\u0430\u0442\u044c 4*32 \u0431\u0430\u0439\u0442 \u0432 \u0447\u0435\u0442\u044b\u0440\u0435 \u0440\u0435\u0433\u0438\u0441\u0442\u0440\u0430, \u0440\u0430\u0441\u0441\u0442\u0430\u0432\u0438\u0442\u044c \u0432 \u043d\u0438\u0445 \u0431\u0430\u0439\u0442\u044b \u0432 \u043d\u0443\u0436\u043d\u043e\u043c \u043f\u043e\u0440\u044f\u0434\u043a\u0435 \u0438 \u043e\u0431\u044a\u0435\u0434\u0438\u043d\u0438\u0442\u044c \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u0438 <code>OR<\/code>, \u0442\u043e \u043f\u043e\u043b\u0443\u0447\u0438\u043c \u043d\u0443\u0436\u043d\u044b\u0439 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442:<\/p>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/dd5\/33d\/8e8\/dd533d8e8cbb39e0431c82d252374e52.png\" width=\"1139\" height=\"877\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/dd5\/33d\/8e8\/dd533d8e8cbb39e0431c82d252374e52.png\"\/><\/figure>\n<p>\u0414\u043b\u044f <code>VPSHUFB<\/code> \u0438 \u0434\u043b\u044f <code>VPERMD<\/code> \u043d\u0443\u0436\u043d\u044b 32 \u0431\u0430\u0439\u0442\u043d\u044b\u0435 \u043c\u0430\u0441\u043a\u0438, \u044f \u0438\u0445 \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0438\u043b \u043a\u0430\u043a \u0433\u043b\u043e\u0431\u0430\u043b\u044c\u043d\u044b\u0435 \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u044b\u0435 \u0432 Go \u0432 \u0444\u0430\u0439\u043b\u0435 <code>fastcopy.go<\/code>:<\/p>\n<pre><code class=\"go\">var ( shuffleMask1 = [32]byte{ 2, 6, 10, 14, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 2, 6, 10, 14, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, }  shuffleMask2 = [32]byte{ 128, 128, 128, 128, 2, 6, 10, 14, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 2, 6, 10, 14, 128, 128, 128, 128, 128, 128, 128, 128, }  shuffleMask3 = [32]byte{ 128, 128, 128, 128, 128, 128, 128, 128, 2, 6, 10, 14, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 2, 6, 10, 14, 128, 128, 128, 128, }  shuffleMask4 = [32]byte{ 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 2, 6, 10, 14, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 2, 6, 10, 14, }  permutateMask = [8]uint32{0, 4, 1, 5, 2, 6, 3, 7} )<\/code><\/pre>\n<p><code>VPSHUFB<\/code> \u0432 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442 \u0432\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u0442 0, \u0435\u0441\u043b\u0438 \u0441\u0442\u0430\u0440\u0448\u0438\u0439 \u0431\u0438\u0442 \u0431\u0430\u0439\u0442\u0430 \u0432 \u043c\u0430\u0441\u043a\u0435 \u0440\u0430\u0432\u0435\u043d 1, \u0438\u043d\u0430\u0447\u0435 \u0432\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u0442 \u0447\u0438\u0441\u043b\u043e \u0438\u0437 \u043f\u043e\u0437\u0438\u0446\u0438\u0438, \u043d\u0430 \u043a\u043e\u0442\u043e\u0440\u0443\u044e \u0443\u043a\u0430\u0437\u044b\u0432\u0430\u0435\u0442 \u0431\u0430\u0439\u0442 \u0432 \u043c\u0430\u0441\u043a\u0435. <code>VPERMD<\/code> \u043f\u0440\u043e\u0441\u0442\u043e \u043f\u0435\u0440\u0435\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u0442 4 \u0431\u0430\u0439\u0442\u043e\u0432\u044b\u0435 \u0441\u043b\u043e\u0432\u0430 \u0432 \u0443\u043a\u0430\u0437\u0430\u043d\u043d\u043e\u043c \u0432 \u043c\u0430\u0441\u043a\u0435 \u043f\u043e\u0440\u044f\u0434\u043a\u0435. <\/p>\n<p>\u0418\u0437 \u0410\u0441\u0441\u0435\u043c\u0431\u043b\u0435\u0440\u0430 \u043a \u044d\u0442\u0438\u043c \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u044b\u043c \u043c\u043e\u0436\u043d\u043e \u0434\u043e\u0431\u0440\u0430\u0442\u044c\u0441\u044f \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e \u043a\u043e\u043d\u0441\u0442\u0440\u0443\u043a\u0446\u0438\u0438 <code>\u00b7\u0438\u043c\u044f\u041f\u0435\u0440\u0435\u043c\u043d\u043d\u043e\u0439(SB)<\/code>, \u0441\u0438\u043c\u0432\u043e\u043b <code>\"\u00b7\"<\/code> \u0432 \u043d\u0430\u0447\u0430\u043b\u0435 \u043e\u0447\u0435\u043d\u044c \u0432\u0430\u0436\u0435\u043d. \u0412 \u0438\u0442\u043e\u0433\u0435 \u043a\u043e\u0434 \u043f\u043e\u043b\u0443\u0447\u0438\u043b\u0441\u044f \u0442\u0430\u043a\u043e\u0439:<\/p>\n<pre><code class=\"go\">TEXT \u00b7CopyAsmAvx(SB),$0-48         MOVQ    srcRGBA+0(FP), AX         MOVQ    dstPaletted+24(FP), CX         MOVQ    CX, DI         ADDQ    $512*512, DI          \/\/ \u041a\u043e\u043f\u0438\u0440\u0443\u0435\u043c \u043c\u0430\u0441\u043a\u0438 \u0432 \u0440\u0435\u0433\u0438\u0441\u0442\u0440\u044b Y10-Y14          VMOVDQU \u00b7shuffleMask1(SB), Y10         VMOVDQU \u00b7shuffleMask2(SB), Y11         VMOVDQU \u00b7shuffleMask3(SB), Y12         VMOVDQU \u00b7shuffleMask4(SB), Y13         VMOVDQU \u00b7permutateMask(SB), Y14  LOOP:         \/\/ \u041a\u043e\u043f\u0438\u0440\u0443\u0435\u043c 128 \u0431\u0430\u0439\u0442 \u0438\u0437 \u043f\u0430\u043c\u044f\u0442\u0438 \u0432 \u0440\u0435\u0433\u0438\u0441\u0442\u0440\u044b Y0-Y4         VMOVDQU (AX), Y0         VMOVDQU 32(AX), Y1         VMOVDQU 64(AX), Y2         VMOVDQU 96(AX), Y3          \/\/ \u041f\u0440\u0438\u043c\u0435\u043d\u044f\u0435\u043c \u043c\u0430\u0441\u043a\u0438, \u0447\u0442\u043e\u0431\u044b \u0440\u0430\u0441\u0441\u0442\u0430\u0432\u0438\u0442\u044c \u0441\u0438\u043d\u044e\u044e \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u0443 \u0432 \u043d\u0443\u0436\u043d\u044b\u0435 \u043f\u043e\u0437\u0438\u0446\u0438\u0438         VPSHUFB Y10, Y0, Y0         VPSHUFB Y11, Y1, Y1         VPSHUFB Y12, Y2, Y2         VPSHUFB Y13, Y3, Y3          \/\/ \u041e\u0431\u044a\u0435\u0434\u0438\u043d\u044f\u0435\u043c \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u043d\u044b\u0435 \u0434\u0430\u043d\u043d\u044b\u0435 \u0432 \u0440\u0435\u0433\u0438\u0441\u0442\u0440 Y0         VPOR Y0, Y1, Y0         VPOR Y2, Y3, Y2         VPOR Y0, Y2, Y0          \/\/ \u0418\u0441\u043f\u0440\u0430\u0432\u043b\u044f\u0435\u043c \u043f\u043e\u0440\u044f\u0434\u043e\u043a         VPERMD Y0, Y14, Y0          \/\/ \u0421\u043e\u0445\u0440\u0430\u043d\u044f\u0435\u043c 32 \u0447\u0438\u0441\u043b\u0430 \u0432 dstPaletted         VMOVDQU Y0, (CX)          ADDQ    $32, CX         ADDQ    $128, AX          CMPQ    DI, CX         JGT     LOOP         RET<\/code><\/pre>\n<p>\u042d\u0442\u043e\u0442 \u0432\u0430\u0440\u0438\u0430\u043d\u0442 \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442 \u0443\u0436\u0435 \u0441\u0438\u043b\u044c\u043d\u043e \u0431\u044b\u0441\u0442\u0440\u0435\u0435, \u0447\u0435\u043c \u0432\u0441\u0435 \u043f\u0440\u0435\u0434\u044b\u0434\u0443\u0449\u0438\u0435:<\/p>\n<pre><code>cpu: AMD Ryzen 7 5800H with Radeon Graphics          BenchmarkCopy BenchmarkCopy-16                      93292    128104 ns\/op BenchmarkCopyAsm-16                   94081    127012 ns\/op BenchmarkCopyAsm1R2W-16              185229     64904 ns\/op BenchmarkCopyAsm1R2WUnrolled-16      240812     49406 ns\/op BenchmarkCopyAsmAcc2-16              155895     76325 ns\/op BenchmarkCopyAcc8-16                 203373     57072 ns\/op BenchmarkCopyAcc8Unrolled-16         218060     51953 ns\/op BenchmarkCopyAsmAvx-16               823080     14464 ns\/op<\/code><\/pre>\n<h2>\u0417\u0430\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0435<\/h2>\n<p>\u041c\u043e\u0436\u043d\u043e \u043b\u0438 \u0435\u0449\u0451 \u0443\u0441\u043a\u043e\u0440\u0438\u0442\u0441\u044f? \u0414\u0443\u043c\u0430\u044e \u0447\u0442\u043e \u0434\u0430, \u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440 \u0435\u0441\u043b\u0438 \u0440\u0430\u0431\u043e\u0442\u0430\u0442\u044c \u0441 \u0432\u044b\u0440\u043e\u0432\u043d\u0435\u043d\u043d\u044b\u043c\u0438 \u0434\u0430\u043d\u043d\u044b\u043c\u0438, \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e \u0435\u0441\u0442\u044c \u0431\u043e\u043b\u0435\u0435 \u043e\u043f\u0442\u0438\u043c\u0430\u043b\u044c\u043d\u044b\u0435 \u0441\u043f\u043e\u0441\u043e\u0431\u044b \u043a\u0430\u043a \u0440\u0435\u0448\u0438\u0442\u044c \u044d\u0442\u0443 \u0437\u0430\u0434\u0430\u0447\u0443, &#8230; \u0415\u0441\u043b\u0438 \u0435\u0441\u0442\u044c \u0438\u0434\u0435\u0438, \u0442\u043e \u043f\u0438\u0448\u0438\u0442\u0435 \u0432 \u043a\u043e\u043c\u043c\u0435\u043d\u0442\u0430\u0440\u0438\u044f\u0445 \u0438\u043b\u0438 \u043f\u0440\u043e\u0432\u0435\u0440\u044f\u0439\u0442\u0435 \u0438\u0445 \u0432 \u043f\u043e\u0445\u043e\u0436\u0435\u0439 \u0437\u0430\u0434\u0430\u0447\u0435 \u043d\u0430 <a href=\"https:\/\/highload.fun\/tasks\/17\" rel=\"noopener noreferrer nofollow\">HighLoad.Fun<\/a>.<\/p>\n<p>\u041f\u043e\u043b\u0435\u0437\u043d\u044b\u0435 \u0441\u0441\u044b\u043b\u043a\u0438:<\/p>\n<ul>\n<li>\n<p><a href=\"https:\/\/go.dev\/doc\/asm\" rel=\"noopener noreferrer nofollow\">https:\/\/go.dev\/doc\/asm<\/a><\/p>\n<\/li>\n<li>\n<p><a href=\"https:\/\/www.amd.com\/system\/files\/TechDocs\/24592.pdf\" rel=\"noopener noreferrer nofollow\">https:\/\/www.amd.com\/system\/files\/TechDocs\/24592.pdf<\/a><\/p>\n<\/li>\n<li>\n<p><a href=\"https:\/\/www.agner.org\/optimize\/instruction_tables.pdf\" rel=\"noopener noreferrer nofollow\">https:\/\/www.agner.org\/optimize\/instruction_tables.pdf<\/a><\/p>\n<\/li>\n<li>\n<p><a href=\"https:\/\/www.intel.com\/content\/www\/us\/en\/docs\/intrinsics-guide\/index.html\" rel=\"noopener noreferrer nofollow\">https:\/\/www.intel.com\/content\/www\/us\/en\/docs\/intrinsics-guide\/index.html<\/a><\/p>\n<\/li>\n<\/ul>\n<\/div>\n<\/div>\n<\/div>\n<p> <!----> <!----><\/div>\n<p> <!----> <!----><br \/> \u0441\u0441\u044b\u043b\u043a\u0430 \u043d\u0430 \u043e\u0440\u0438\u0433\u0438\u043d\u0430\u043b \u0441\u0442\u0430\u0442\u044c\u0438 <a href=\"https:\/\/habr.com\/ru\/post\/720582\/\"> https:\/\/habr.com\/ru\/post\/720582\/<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<div><\/div>\n<div id=\"post-content-body\">\n<div>\n<div class=\"article-formatted-body article-formatted-body article-formatted-body_version-2\">\n<div xmlns=\"http:\/\/www.w3.org\/1999\/xhtml\">\n<p>\u041f\u0440\u0438\u0432\u0435\u0442, \u0425\u0430\u0431\u0440!<\/p>\n<p>\u0412 <a href=\"https:\/\/habr.com\/ru\/post\/717716\/\" rel=\"noopener noreferrer nofollow\">\u043f\u0440\u043e\u0448\u043b\u043e\u0439 \u0441\u0442\u0430\u0442\u044c\u0435<\/a> \u044f \u0440\u0430\u0441\u0441\u043a\u0430\u0437\u044b\u0432\u0430\u043b \u043e\u0431 \u0443\u0441\u043a\u043e\u0440\u0435\u043d\u0438\u0438 \u043a\u043e\u043f\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u043e\u0432 \u043e\u0434\u043d\u043e\u0433\u043e \u0441\u043b\u0430\u0439\u0441\u0430 \u0432 \u0434\u0440\u0443\u0433\u043e\u0439 \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e \u0441\u0440\u0435\u0434\u0441\u0442\u0432 Go. \u0412 \u044d\u0442\u043e\u0442 \u0440\u0430\u0437 \u044f \u0440\u0435\u0448\u0438\u043b \u043f\u043e\u0439\u0442\u0438 \u0434\u0430\u043b\u044c\u0448\u0435 \u0438 \u043f\u043e\u0441\u043c\u043e\u0442\u0440\u0435\u0442\u044c, \u0447\u0442\u043e \u043c\u043e\u0436\u043d\u043e \u0434\u043e\u0441\u0442\u0438\u0447\u044c, \u043d\u0430\u0447\u0430\u0432 \u0440\u0430\u0437\u0433\u043e\u0432\u0430\u0440\u0438\u0432\u0430\u0442\u044c \u0441 \u043f\u0440\u043e\u0446\u0435\u0441\u0441\u043e\u0440\u043e\u043c \u043d\u0430 \u0435\u0433\u043e \u044f\u0437\u044b\u043a\u0435. \u042f \u0432\u044b\u0431\u0440\u0430\u043b \u043e\u0434\u043d\u0443 \u0438\u0437 \u043e\u043f\u0442\u0438\u043c\u0438\u0437\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u044b\u0445 \u0432\u0435\u0440\u0441\u0438\u0439 \u0444\u0443\u043d\u043a\u0446\u0438\u0438 <code>Copy<\/code> \u0432 \u043a\u0430\u0447\u0435\u0441\u0442\u0432\u0435 \u043e\u0431\u044a\u0435\u043a\u0442\u0430 \u0438\u0441\u0441\u043b\u0435\u0434\u043e\u0432\u0430\u043d\u0438\u044f \u0438\u0437 <a href=\"https:\/\/habr.com\/ru\/post\/716292\/\" rel=\"noopener noreferrer nofollow\">\u0440\u0435\u0448\u0435\u043d\u0438\u044f \u0437\u0430\u0434\u0430\u0447\u0438<\/a> VK Cup&#8217;22\/23, \u043a\u043e\u0442\u043e\u0440\u0430\u044f \u043a\u043e\u043f\u0438\u0440\u0443\u0435\u0442 \u0442\u043e\u043b\u044c\u043a\u043e \u0441\u0438\u043d\u0438\u0439 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442 RGBA \u0432 Paletted \u043a\u0430\u0440\u0442\u0438\u043d\u043a\u0443:<\/p>\n<pre><code class=\"go\">func Copy(srcRGBA, dstPaletted []uint8) { srcPtr := unsafe.Add(unsafe.Pointer(&amp;srcRGBA[0]), 2) dstPtr := unsafe.Pointer(&amp;dstPaletted[0]) for range dstPaletted { *(*uint8)(dstPtr) = *(*uint8)(srcPtr) dstPtr = unsafe.Add(dstPtr, 1) srcPtr = unsafe.Add(srcPtr, 4) } }<\/code><\/pre>\n<p>\u041d\u0438\u0436\u0435 \u044f \u0440\u0430\u0441\u0441\u043a\u0430\u0436\u0443 \u043a\u0430\u043a \u0435\u0451 \u0443\u0441\u043a\u043e\u0440\u0438\u0442\u044c \u043f\u043e\u0447\u0442\u0438 \u0432 10 \u0440\u0430\u0437.<\/p>\n<h2>Disclaimer<\/h2>\n<p>\u0421 \u0432\u0435\u0440\u043e\u044f\u0442\u043d\u043e\u0441\u0442\u044c\u044e 99.9% \u043f\u0440\u0438\u0432\u0435\u0434\u0451\u043d\u043d\u043e\u0435 \u043d\u0438\u0436\u0435 \u043d\u0438\u043a\u043e\u0433\u0434\u0430 \u043d\u0435 \u043f\u0440\u0438\u0433\u043e\u0434\u0438\u0442\u0441\u044f \u0432 \u0440\u0435\u0430\u043b\u044c\u043d\u043e\u0439 \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u043a\u0435, \u0431\u043e\u043b\u0435\u0435 \u0442\u043e\u0433\u043e, \u044f \u0430\u0431\u0441\u043e\u043b\u044e\u0442\u043d\u043e \u043d\u0435 \u0433\u0430\u0440\u0430\u043d\u0442\u0438\u0440\u0443\u044e, \u0447\u0442\u043e \u0434\u0430\u043d\u043d\u044b\u0439 \u043a\u043e\u0434 \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f 100% \u043d\u0430\u0434\u0451\u0436\u043d\u044b\u043c. \u0412\u043e\u043e\u0431\u0449\u0435 \u043f\u043e\u0441\u043b\u0435\u0434\u043d\u0438\u0439 \u0440\u0430\u0437 \u044f \u0438\u0433\u0440\u0430\u043b\u0441\u044f \u0441 \u0430\u0441\u0441\u0435\u043c\u0431\u043b\u0435\u0440\u043e\u043c \u043f\u043e\u0447\u0442\u0438 20 \u043b\u0435\u0442 \u043d\u0430\u0437\u0430\u0434 \u0438 \u0432\u0441\u0451 \u043e\u043f\u0438\u0441\u0430\u043d\u043d\u043e\u0435 \u0437\u0434\u0435\u0441\u044c \u0431\u044b\u043b\u043e \u0441\u0434\u0435\u043b\u0430\u043d\u043e \u0447\u0438\u0441\u0442\u043e \u0432 \u0438\u0441\u0441\u043b\u0435\u0434\u043e\u0432\u0430\u0442\u0435\u043b\u044c\u0441\u043a\u0438\u0445 \u0446\u0435\u043b\u044f\u0445 \u0434\u043b\u044f \u0441\u0430\u043c\u043e\u0440\u0430\u0437\u0432\u0438\u0442\u0438\u044f.<\/p>\n<h2>\u0410\u0441\u0441\u0435\u043c\u0431\u043b\u0435\u0440 \u0432 Go<\/h2>\n<p>\u0417\u043d\u0430\u043a\u043e\u043c\u0441\u0442\u0432\u043e \u0441 \u0410\u0441\u0441\u0435\u043c\u0431\u043b\u0435\u0440\u043e\u043c \u0432 Go \u044f \u043d\u0430\u0447\u0430\u043b \u0441 \u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442\u0430 &#171;<a href=\"https:\/\/go.dev\/doc\/asm\" rel=\"noopener noreferrer nofollow\">A Quick Guide to Go&#8217;s Assembler<\/a>&#171;. \u0412 \u043d\u0451\u043c \u043a\u0440\u0430\u0442\u043a\u043e \u043e\u043f\u0438\u0441\u0430\u043d\u043e \u0447\u0442\u043e \u044d\u0442\u043e \u0442\u0430\u043a\u043e\u0435 \u0438 \u043a\u0430\u043a \u043e\u043d\u043e \u0443\u0441\u0442\u0440\u043e\u0435\u043d\u043e, \u043d\u043e, \u0435\u0441\u043b\u0438 \u0447\u0435\u0441\u0442\u043d\u043e, \u0441 \u043f\u0435\u0440\u0432\u043e\u0433\u043e \u0440\u0430\u0437\u0430 \u043c\u0430\u043b\u043e \u0447\u0442\u043e \u043f\u043e\u043d\u044f\u0442\u043d\u043e, \u043a\u0440\u043e\u043c\u0435 \u0442\u043e\u0433\u043e, \u0447\u0442\u043e \u044d\u0442\u043e \u043d\u0435 \u043f\u0440\u0438\u0432\u044b\u0447\u043d\u044b\u0439 \u0430\u0441\u0441\u0435\u043c\u0431\u043b\u0435\u0440, \u0430 Plan 9 Assembler. \u041f\u043e\u044d\u0442\u043e\u043c\u0443 \u043f\u0435\u0440\u0432\u043e\u0435 \u0447\u0442\u043e \u043f\u0440\u0438\u0445\u043e\u0434\u0438\u0442 \u0432 \u0433\u043e\u043b\u043e\u0432\u0443, \u044d\u0442\u043e \u043f\u043e\u0441\u043c\u043e\u0442\u0440\u0435\u0442\u044c \u043a\u0430\u043a \u0432\u044b\u0433\u043b\u044f\u0434\u0438\u0442 \u043f\u0440\u0438\u0432\u0435\u0434\u0451\u043d\u043d\u0430\u044f \u0432\u044b\u0448\u0435 \u0444\u0443\u043d\u043a\u0446\u0438\u044f <code>Copy<\/code> \u043d\u0430 \u043d\u0451\u043c. \u041a \u0441\u0447\u0430\u0441\u0442\u044c\u044e, Go \u043f\u0440\u0435\u0434\u043e\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u0442 \u0444\u043b\u0430\u0433 \u043a\u043e\u043c\u043f\u0438\u043b\u044f\u0446\u0438\u0438 <code>-gcflags \"-S\", \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0432\u044b\u0432\u043e\u0434\u0438\u0442 \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u0443 \u0432 \u0432\u0438\u0434\u0435 \u043c\u0430\u0448\u0438\u043d\u043d\u043e\u0433\u043e \u043a\u043e\u0434\u0430<\/code>. \u0412\u0441\u044e \u0440\u0430\u0431\u043e\u0442\u0443 \u044f \u0434\u0435\u043b\u0430\u043b \u0432 *<code>_test.go<\/code> \u0444\u0430\u0439\u043b\u0435, \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u0434\u043b\u044f \u0435\u0433\u043e \u043f\u0440\u0435\u0432\u0440\u0430\u0449\u0435\u043d\u0438\u044f \u0432 \u043a\u043e\u0434 \u043d\u0430 \u0410\u0441\u0441\u0435\u043c\u0431\u043b\u0435\u0440\u0435 \u043d\u0430\u0434\u043e \u0432\u044b\u043f\u043e\u043b\u043d\u0438\u0442\u044c <code>go test -c  -gcflags \"-S -B\" .\/fastcopy<\/code>, \u0433\u0434\u0435 <code>fastcopy<\/code> &#8212;  \u0434\u0438\u0440\u0435\u043a\u0442\u043e\u0440\u0438\u044f \u0441 \u0438\u0441\u0445\u043e\u0434\u043d\u0438\u043a\u0430\u043c\u0438. \u042f \u0442\u0430\u043a\u0436\u0435 \u043e\u0442\u043a\u043b\u044e\u0447\u0438\u043b Bounds Check \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e \u0444\u043b\u0430\u0433\u0430 <code>-B<\/code>, \u0447\u0442\u043e\u0431\u044b \u0443\u043f\u0440\u043e\u0441\u0442\u0438\u0442\u044c \u043a\u043e\u0434. \u041d\u0430 \u0432\u044b\u0445\u043e\u0434\u0435 \u0431\u0443\u0434\u0435\u0442 \u0434\u043e\u0432\u043e\u043b\u044c\u043d\u043e \u043c\u043d\u043e\u0433\u043e \u0442\u0435\u043a\u0441\u0442\u0430, \u043d\u043e \u0441\u0430\u043c\u043e\u0435 \u0438\u043d\u0442\u0435\u0440\u0435\u0441\u043d\u043e\u0435, \u044d\u0442\u043e \u043a\u0430\u043a \u0432\u044b\u0433\u043b\u044f\u0434\u0438\u0442 \u0444\u0443\u043d\u043a\u0446\u0438\u044f <code>Copy<\/code>:<\/p>\n<pre><code class=\"go\">0x0000 00000     TEXT    round-3\/fastcopy.Copy(SB), NOSPLIT|ABIInternal, $0-48 0x0000 00000     MOVQ    AX, round-3\/fastcopy.srcRGBA+8(FP) 0x0005 00005     MOVQ    DI, round-3\/fastcopy.dstPaletted+32(FP) 0x000a 00010     FUNCDATA        $0, gclocals\u00b7cNGUyZq94N9QFR70tEjj5A==(SB) 0x000a 00010     FUNCDATA        $1, gclocals\u00b7J5F+7Qw7O7ve2QcWC7DpeQ==(SB) 0x000a 00010     FUNCDATA        $5, round-3\/fastcopy.Copy.arginfo1(SB) 0x000a 00010     FUNCDATA        $6, round-3\/fastcopy.Copy.argliveinfo(SB) 0x000a 00010     PCDATA  $3, $1 0x000a 00010     ADDQ    $2, AX 0x000e 00014     XORL    CX, CX 0x0010 00016     JMP     33 0x0012 00018     MOVBLZX (AX), DX 0x0015 00021     MOVB    DL, (DI) 0x0017 00023     INCQ    CX 0x001a 00026     INCQ    DI 0x001d 00029     ADDQ    $4, AX 0x0021 00033     CMPQ    SI, CX 0x0024 00036     JGT     18 0x0026 00038     RET<\/code><\/pre>\n<p>\u0421\u0442\u0440\u043e\u043a\u0430 1 &#8212; \u044d\u0442\u043e \u043e\u043f\u0438\u0441\u0430\u043d\u0438\u0435 \u0444\u0443\u043d\u043a\u0446\u0438\u0438, \u0441\u043e\u0441\u0442\u043e\u044f\u0449\u0435\u0435 \u0438\u0437 \u043d\u0430\u0437\u0432\u0430\u043d\u0438\u044f \u0444\u0443\u043d\u043a\u0446\u0438\u0438, \u0444\u043b\u0430\u0433\u043e\u0432 \u0438 \u0440\u0430\u0437\u043c\u0435\u0440\u0430 \u0441\u0442\u0435\u043a\u0430. \u0421\u0442\u0435\u043a \u0440\u0430\u0432\u0435\u043d 48 \u0431\u0430\u0439\u0442\u0430\u043c, \u0442\u0430\u043a \u043a\u0430\u043a \u0444\u0443\u043d\u043a\u0446\u0438\u044f \u043f\u043e\u043b\u0443\u0447\u0430\u0435\u0442 2 \u0441\u043b\u0430\u0439\u0441\u0430 \u0432 \u043a\u0430\u0447\u0435\u0441\u0442\u0432\u0435 \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u043e\u0432, \u0430 \u043a\u0430\u0436\u0434\u044b\u0439 \u0441\u043b\u0430\u0439\u0441 \u0441\u043e\u0441\u0442\u043e\u0438\u0442 \u0438\u0437 \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u044b \u0441 \u0442\u0440\u0435\u043c\u044f \u043f\u043e\u043b\u044f\u043c\u0438 (\u0443\u043a\u0430\u0437\u0430\u0442\u0435\u043b\u044c \u043d\u0430 \u043c\u0430\u0441\u0441\u0438\u0432 \u0441 \u0434\u0430\u043d\u043d\u044b\u043c\u0438, \u0434\u043b\u0438\u043d\u0430 \u0438 \u043a\u0430\u043f\u0430\u0441\u0438\u0442\u0438), \u043a\u0430\u0436\u0434\u043e\u0435 \u0438\u0437 \u043a\u043e\u0442\u043e\u0440\u044b\u0445 \u0440\u0430\u0432\u043d\u043e 8 \u0431\u0430\u0439\u0442. \u0412 \u0441\u0442\u0440\u043e\u043a\u0430\u0445 2 \u0438 3 \u0432 \u0440\u0435\u0433\u0438\u0441\u0442\u0440\u044b \u043f\u043e\u043c\u0435\u0449\u0430\u044e\u0442\u0441\u044f \u0438\u0445 \u0434\u043b\u0438\u043d\u044b.<\/p>\n<p>\u0421\u0442\u0440\u043e\u043a\u0438 4-8 \u0441\u043e\u043e\u0431\u0449\u0430\u044e\u0442 \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u044e \u0434\u043b\u044f Garbage Collector, \u0430 \u0434\u0430\u043b\u0435\u0435 \u0443\u0436\u0435 \u0438\u0434\u0451\u0442 \u0441\u0430\u043c\u043e \u0442\u0435\u043b\u043e \u0444\u0443\u043d\u043a\u0446\u0438\u0438.<\/p>\n<p>\u0418\u0437 \u043d\u0435\u043e\u0431\u044b\u0447\u043d\u043e\u0433\u043e \u0432 \u0433\u043b\u0430\u0437\u0430 \u0431\u0440\u043e\u0441\u0430\u0435\u0442\u0441\u044f \u043e\u0442\u0441\u0443\u0442\u0441\u0442\u0432\u0438\u0435 \u0440\u0435\u0433\u0438\u0441\u0442\u0440\u043e\u0432 <code>RAX<\/code>, <code>EAX<\/code>, &#8230;, \u0432\u0435\u0437\u0434\u0435 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f <code>AX<\/code>. \u041f\u0435\u0440\u0432\u0430\u044f \u043c\u044b\u0441\u043b\u044c \u0431\u044b\u043b\u0430: \u043f\u043e\u0447\u0435\u043c\u0443 \u0432\u0441\u0451 16 \u0431\u0438\u0442\u043d\u043e\u0435? \u041d\u0430 \u0441\u0430\u043c\u043e\u043c \u0434\u0435\u043b\u0435 \u0440\u0430\u0437\u043c\u0435\u0440 \u0440\u0435\u0433\u0438\u0441\u0442\u0440\u043e\u0432 \u0437\u0430\u0434\u0430\u0451\u0442\u0441\u044f \u043a\u043e\u043c\u0430\u043d\u0434\u043e\u0439, \u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440 <code>MOVQ $1, AX<\/code> &#8212; \u044d\u0442\u043e <code>MOVQ $1, %RAX<\/code>, \u0430 <code>MOVD $1, AX<\/code> &#8212; \u044d\u0442\u043e <code>MOVD $1, %EAX<\/code>.<\/p>\n<h2>\u041f\u0435\u0440\u0432\u0430\u044f \u0444\u0443\u043d\u043a\u0446\u0438\u044f \u043d\u0430 \u0410\u0441\u0441\u0435\u043c\u0431\u043b\u0435\u0440\u0435.<\/h2>\n<p>\u041f\u0440\u0435\u0436\u0434\u0435 \u0447\u0435\u043c \u0441\u043e\u0437\u0434\u0430\u0432\u0430\u0442\u044c \u0444\u0443\u043d\u043a\u0446\u0438\u044e \u043d\u0430 \u0410\u0441\u0441\u0435\u043c\u0431\u043b\u0435\u0440\u0435, \u0441\u043d\u0430\u0447\u0430\u043b\u0430 \u043d\u0430\u0434\u043e \u043e\u043f\u0438\u0441\u0430\u0442\u044c \u0435\u0451 \u043d\u0430 Go, \u0434\u043b\u044f \u044d\u0442\u043e\u0433\u043e \u044f \u0432 \u0444\u0430\u0439\u043b\u0435 <code>fastcopy.go<\/code> \u0440\u044f\u0434\u043e\u043c \u0441 \u0444\u0443\u043d\u043a\u0446\u0438\u0435\u0439 <code>Copy<\/code> \u0434\u043e\u0431\u0430\u0432\u0438\u043b \u0444\u0443\u043d\u043a\u0446\u0438\u044e <code>CopyAsm<\/code> \u0431\u0435\u0437 \u0442\u0435\u043b\u0430:<\/p>\n<pre><code class=\"go\">func CopyAsm(srcRGBA, dstPaletted []uint8)<\/code><\/pre>\n<p>\u0420\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044e \u043d\u0430 \u0430\u0441\u0441\u0435\u043c\u0431\u043b\u0435\u0440\u0435 \u043d\u0430\u0434\u043e \u043f\u043e\u043b\u043e\u0436\u0438\u0442\u044c \u0432 \u0444\u0430\u0439\u043b \u0441 \u0440\u0430\u0441\u0448\u0438\u0440\u0435\u043d\u0438\u0435\u043c .s, \u0432 \u043c\u043e\u0451\u043c \u0441\u043b\u0443\u0447\u0430\u0435 \u044d\u0442\u043e <code>fastcopy_amd64.s<\/code>. \u0421\u0443\u0444\u0444\u0438\u043a\u0441  <code>_amd64<\/code> \u043d\u0443\u0436\u0435\u043d \u0434\u043b\u044f \u0442\u043e\u0433\u043e, \u0447\u0442\u043e\u0431\u044b \u043d\u0435 \u0434\u0430\u0442\u044c \u0441\u043e\u0431\u0440\u0430\u0442\u044c\u0441\u044f \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044e \u043d\u0430 \u0434\u0440\u0443\u0433\u0438\u0445 \u0430\u0440\u0445\u0438\u0442\u0435\u043a\u0442\u0443\u0440\u0430\u0445, \u0432\u0435\u0434\u044c \u0434\u043b\u044f \u043d\u0438\u0445 \u043d\u0443\u0436\u043d\u0430 \u0431\u0443\u0434\u0435\u0442 \u0434\u0440\u0443\u0433\u0430\u044f \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044f. \u041f\u0435\u0440\u0432\u0430\u044f \u0432\u0435\u0440\u0441\u0438\u044f \u043f\u043e\u043b\u0443\u0447\u0438\u043b\u0430\u0441\u044c \u0442\u0430\u043a\u0430\u044f:<\/p>\n<pre><code class=\"go\">TEXT \u00b7CopyAsm(SB),$0-48                 \/\/ \u0418\u043c\u044f \u0444\u0443\u043d\u043a\u0446\u0438\u0438 \u0434\u043e\u043b\u0436\u043d\u043e \u043d\u0430\u0447\u0438\u043d\u0430\u0442\u044c\u0441\u044f \u0441 \u00b7, \u0444\u043b\u0430\u0433\u043e\u0432 \u043d\u0435\u0442, \u0440\u0430\u0437\u043c\u0435\u0440 \u0441\u0442\u0435\u043a\u0430 48 \u0431\u0430\u0439\u0442         MOVQ    srcRGBA+0(FP), AX       \/\/ \u0412 AX \u043a\u043b\u0430\u0434\u0451\u043c \u0430\u0434\u0440\u0435\u0441 \u043c\u0430\u0441\u0441\u0438\u0432\u0430 srcRGBA         ADDQ    $2, AX                  \/\/ \u0418 \u0441\u043c\u0435\u0449\u0430\u0435\u043c \u0435\u0433\u043e \u043d\u0430 2, \u0442.\u043a. \u043d\u0443\u0436\u0435\u043d \u0442\u043e\u043b\u044c\u043a\u043e \u0441\u0438\u043d\u0438\u0439 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442         MOVQ    dstPaletted+24(FP), CX  \/\/ \u0412 CX \u043a\u043b\u0430\u0434\u0451\u043c \u0430\u0434\u0440\u0435\u0441 \u043c\u0430\u0441\u0441\u0438\u0432\u0430 dstPaletted         MOVQ    CX, BX                  \/\/ \u0414\u043b\u044f \u0432\u044b\u0445\u043e\u0434\u0430 \u0438\u0437 \u0446\u0438\u043a\u043b\u0430 \u043d\u0443\u0436\u0435\u043d \u0430\u0434\u0440\u0435\u0441 \u043f\u043e\u0441\u043b\u0435\u0434\u043d\u0435\u0433\u043e \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u0430 dstPaletted         ADDQ    $512*512, BX            \/\/ \u0411\u0435\u0440\u0451\u043c \u043d\u0430\u0447\u0430\u043b\u044c\u043d\u044b\u0439 \u0430\u0434\u0440\u0435\u0441 \u0438 \u0434\u043e\u0431\u0430\u0432\u043b\u044f\u0435\u043c \u043a \u043d\u0435\u043c\u0443 512*512  LOOP:   MOVBLZX (AX), DX                \/\/ \u041a\u043e\u043f\u0438\u0440\u0443\u0435\u043c 1 \u0431\u0430\u0439\u0442 \u043f\u043e \u0430\u0434\u0440\u0435\u0441\u0443 \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0445\u0440\u0430\u043d\u0438\u0442\u0441\u044f \u0432 AX (srcRGBA) \u0432 DX         MOVB    DL, (CX)                \/\/ \u0418 \u0437\u0430\u0442\u0435\u043c \u043a\u043e\u043f\u0438\u0440\u0443\u0435\u043c \u0435\u0433\u043e \u0432 \u044f\u0447\u0435\u0439\u043a\u0443 \u043c\u0430\u0441\u0441\u0438\u0432\u0430 dstPaletted.          INCQ    CX                      \/\/ \u0423\u0432\u0435\u043b\u0438\u0447\u0438\u0432\u0430\u0435\u043c \u0430\u0434\u0440\u0435\u0441 \u0442\u043a\u0443\u0449\u0435\u0439 \u044f\u0447\u0435\u0439\u043a\u0438 dstPaletted \u043d\u0430 1         ADDQ    $4, AX                  \/\/ \u0423\u0432\u0435\u043b\u0438\u0447\u0438\u0432\u0430\u0435\u043c \u0430\u0434\u0440\u0435\u0441 \u0442\u043a\u0443\u0449\u0435\u0439 \u044f\u0447\u0435\u0439\u043a\u0438 srcRGBA \u043d\u0430 4          CMPQ    BX, CX                  \/\/ \u0415\u0441\u043b\u0438 \u043d\u0435 \u0434\u043e\u0441\u0442\u0438\u0433\u043b\u0438 \u043a\u043e\u043d\u0446\u0430         JGT     LOOP                    \/\/ \u0422\u043e \u0438\u0434\u0451\u043c \u043d\u0430 \u0441\u0442\u0440\u043e\u043a\u0443 8         RET                             \/\/ \u0418\u043d\u0430\u0447\u0435 \u0432\u044b\u0445\u043e\u0434<\/code><\/pre>\n<p>\u0412 \u0434\u0430\u043d\u043d\u043e\u0439 \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438 \u044f \u0438\u0437\u0431\u0430\u0432\u0438\u043b\u0441\u044f \u043e\u0442 \u0445\u0440\u0430\u043d\u0435\u043d\u0438\u044f \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u043e\u0439 \u0446\u0438\u043a\u043b\u0430 \u0432 \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u043e\u043c \u0440\u0435\u0433\u0438\u0441\u0442\u0440\u0435, \u0430 \u0442\u0430\u043a \u043e\u043d\u0430 \u043e\u0447\u0435\u043d\u044c \u043f\u043e\u0445\u043e\u0436\u0430 \u043d\u0430 \u0442\u043e, \u0447\u0442\u043e \u0433\u0435\u043d\u0435\u0440\u0438\u0440\u0443\u0435\u0442 Go. \u0415\u0441\u043b\u0438 \u0441\u0440\u0430\u0432\u043d\u0438\u0442\u044c \u0438\u0445 \u043f\u0440\u043e\u0438\u0437\u0432\u043e\u0434\u0438\u0442\u0435\u043b\u044c\u043d\u043e\u0441\u0442\u044c, \u0442\u043e, \u043a\u0430\u043a \u0438 \u043e\u0436\u0438\u0434\u0430\u043b\u043e\u0441\u044c, \u043e\u043d\u0438 \u043f\u0440\u0438\u043c\u0435\u0440\u043d\u043e \u043d\u0430 \u043e\u0434\u043d\u043e\u043c \u0443\u0440\u043e\u0432\u043d\u0435: <\/p>\n<pre><code>cpu: AMD Ryzen 7 5800H with Radeon Graphics          BenchmarkCopy BenchmarkCopy-16                      93292    128104 ns\/op BenchmarkCopyAsm-16                   94081    127012 ns\/op<\/code><\/pre>\n<h2>1. \u0423\u043c\u0435\u043d\u044c\u0448\u0430\u0435\u043c \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u0447\u0442\u0435\u043d\u0438\u0439 \u0438\u0437 \u043f\u0430\u043c\u044f\u0442\u0438<\/h2>\n<p>\u0412 \u0441\u0442\u0440\u043e\u043a\u0435 8 \u0444\u0443\u043d\u043a\u0446\u0438\u0438 <code>CopyAsm<\/code> \u0447\u0438\u0442\u0430\u0435\u0442\u0441\u044f \u0442\u043e\u043b\u044c\u043a\u043e 1 \u0431\u0430\u0439\u0442 \u0438\u0437 \u043f\u0430\u043c\u044f\u0442\u0438 \u0432 \u0440\u0435\u0433\u0438\u0441\u0442\u0440 \u0438\u043c\u0435\u044e\u0449\u0438\u0439 \u0440\u0430\u0437\u043c\u0435\u0440 8 \u0431\u0430\u0439\u0442. \u041f\u0435\u0440\u0432\u043e\u0435 \u0447\u0442\u043e \u043f\u0440\u0438\u0445\u043e\u0434\u0438\u0442 \u0432 \u0433\u043e\u043b\u043e\u0432\u0443, \u0430 \u043d\u0435 \u043f\u0440\u043e\u0447\u0438\u0442\u0430\u0442\u044c \u043b\u0438 \u0437\u0430 \u0440\u0430\u0437 \u0432\u0441\u0435 8 \u0431\u0430\u0439\u0442, \u0430 \u0434\u0430\u043b\u044c\u0448\u0435 \u0443\u0436\u0435 \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e SHRQ \u0434\u043e\u0441\u0442\u0430\u0442\u044c \u0432\u0442\u043e\u0440\u043e\u0439 \u044d\u043b\u0435\u043c\u0435\u043d\u0442:<\/p>\n<figure class=\"full-width\"><\/figure>\n<p>\u041a\u043e\u0434 \u043f\u043e\u043b\u0443\u0447\u0438\u043b\u0441\u044f \u0442\u0430\u043a\u0438\u043c:<\/p>\n<pre><code class=\"go\">TEXT \u00b7CopyAsm1R2W(SB),$0-48         MOVQ    srcRGBA+0(FP), AX         ADDQ    $2, AX         MOVQ    dstPaletted+24(FP), CX         MOVQ    CX, BX         ADDQ    $512*512, BX  LOOP:         MOVQ (AX), DX      \/\/ \u041a\u043e\u043f\u0438\u0440\u0443\u0435\u043c 8 \u0431\u0430\u0439\u0442 \u0432 DX         MOVB    DL, (CX)   \/\/ \u0421\u043e\u0445\u0440\u0430\u043d\u044f\u0435\u043c \u043f\u0435\u0440\u0432\u044b\u0439 \u0441\u0438\u043d\u0438\u0439 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442         SHRQ    $32, DX    \/\/ \u0421\u043c\u0435\u0449\u0430\u0435\u043c \u043d\u0430 4 \u0431\u0430\u0439\u0442\u0430         MOVB    DL, 1(CX)  \/\/ \u0421\u043e\u0445\u0440\u0430\u043d\u044f\u0435\u043c \u0432\u0442\u043e\u0440\u043e\u0439 \u0441\u0438\u043d\u0438\u0439 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442          ADDQ    $2, CX     \/\/ \u0410\u0434\u0440\u0435\u0441 \u043f\u043e\u043b\u0443\u0447\u0430\u0442\u0435\u043b\u044f \u0441\u043c\u0435\u0449\u0430\u0435\u043c \u0443\u0436\u0435 \u043d\u0430 2, \u0442.\u043a. \u0441\u043e\u0445\u0440\u0430\u043d\u0438\u043b\u0438 2 \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u0430         ADDQ    $8, AX     \/\/ \u0410 \u0430\u0434\u0440\u0435\u0441 \u0438\u0441\u0442\u043e\u0447\u043d\u0438\u043a\u0430 \u043d\u0430 \u043f\u0440\u043e\u0447\u0438\u0442\u0430\u043d\u043d\u044b\u0435 \u0437\u0430 \u0440\u0430\u0437 8 \u0431\u0430\u0439\u0442          CMPQ    BX, CX         JGT     LOOP         RET<\/code><\/pre>\n<p>\u0421 \u0442\u043e\u0447\u043a\u0438 \u0437\u0440\u0435\u043d\u0438\u044f \u043f\u0440\u043e\u0438\u0437\u0432\u043e\u0434\u0438\u0442\u0435\u043b\u044c\u043d\u043e\u0441\u0442\u0438 \u0432\u0441\u0451 \u0441\u0442\u0430\u043b\u043e \u0441\u0438\u043b\u044c\u043d\u043e \u043b\u0443\u0447\u0448\u0435:<\/p>\n<pre><code>cpu: AMD Ryzen 7 5800H with Radeon Graphics          BenchmarkCopy BenchmarkCopy-16                      93292    128104 ns\/op BenchmarkCopyAsm-16                   94081    127012 ns\/op BenchmarkCopyAsm1R2W-16              185229     64904 ns\/op<\/code><\/pre>\n<p>\u0410 \u0435\u0441\u043b\u0438 \u0435\u0449\u0451 \u0440\u0430\u0437\u0432\u0435\u0440\u043d\u0443\u0442\u044c \u0446\u0438\u043a\u043b, \u0442\u043e \u043c\u043e\u0436\u043d\u043e \u0434\u043e\u0431\u0438\u0442\u044c\u0441\u044f \u0435\u0449\u0451 \u0431\u043e\u043b\u044c\u0448\u0435\u0439 \u043f\u0440\u043e\u0438\u0437\u0432\u043e\u0434\u0438\u0442\u0435\u043b\u044c\u043d\u043e\u0441\u0442\u0438:<\/p>\n<pre><code>cpu: AMD Ryzen 7 5800H with Radeon Graphics          BenchmarkCopy BenchmarkCopy-16                      93292    128104 ns\/op BenchmarkCopyAsm-16                   94081    127012 ns\/op BenchmarkCopyAsm1R2W-16              185229     64904 ns\/op BenchmarkCopyAsm1R2WUnrolled-16      240812     49406 ns\/op<\/code><\/pre>\n<pre><code class=\"go\">TEXT \u00b7CopyAsm1R2WUnrolled(SB),$0-48         MOVQ    srcRGBA+0(FP), AX         ADDQ    $2, AX         MOVQ    dstPaletted+24(FP), CX         MOVQ    CX, BX         ADDQ    $512*512, BX  LOOP:         \/\/ 1         MOVQ    (AX), DX         MOVB    DL, (CX)         SHRQ    $32, DX         MOVB    DL, 1(CX)          \/\/ 2         MOVQ    8(AX), DX         MOVB    DL, 2(CX)         SHRQ    $32, DX         MOVB    DL, 3(CX)          ADDQ    $16, AX         ADDQ    $4, CX          CMPQ    BX, CX         JGT     LOOP         RET<\/code><\/pre>\n<p>\u0423\u0432\u0435\u043b\u0438\u0447\u0435\u043d\u0438\u0435 \u0440\u0430\u0437\u0432\u0451\u0440\u0442\u043a\u0438 \u043f\u0440\u043e\u0444\u0438\u0442\u0430 \u043d\u0435 \u0434\u0430\u043b\u043e, \u043f\u043e \u043a\u0440\u0430\u0439\u043d\u0435\u0439 \u043c\u0435\u0440\u0435 \u043d\u0430 \u043c\u043e\u0451\u043c CPU.<\/p>\n<h2>2. \u0423\u043c\u0435\u043d\u044c\u0448\u0430\u0435\u043c \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u0437\u0430\u043f\u0438\u0441\u0435\u0439 \u0432 \u043f\u0430\u043c\u044f\u0442\u044c<\/h2>\n<p>\u0410\u043d\u0430\u043b\u0438\u0437\u0438\u0440\u0443\u044f \u043a\u043e\u0434, \u043f\u043e\u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u0436\u0435\u043b\u0430\u043d\u0438\u0435 \u0438\u0437\u0431\u0430\u0432\u0438\u0442\u044c\u0441\u044f \u043e\u0442 \u0434\u0432\u0443\u0445 <code>MOVB DL, (CX)<\/code> \u0438 \u043f\u0440\u0435\u0432\u0440\u0430\u0442\u0438\u0442\u044c \u0438\u0445 \u0432 \u043e\u0434\u0438\u043d <code>MOVW BX, (CX)<\/code>, \u0433\u0434\u0435 \u0440\u0435\u0433\u0438\u0441\u0442\u0440 <code>BX<\/code> \u0431\u0443\u0434\u0435\u0442 \u0445\u0440\u0430\u043d\u0438\u0442\u044c 2 \u0431\u0430\u0439\u0442\u0430:<\/p>\n<figure class=\"full-width\"><\/figure>\n<pre><code class=\"go\">TEXT \u00b7CopyAsmAcc2(SB),$0-48         MOVQ    srcRGBA+0(FP), AX         ADDQ    $2, AX         MOVQ    dstPaletted+24(FP), CX         MOVQ    CX, DI         ADDQ    $512*512, DI  LOOP:   MOVQ    (AX), DX   \/\/ \u041a\u043e\u043f\u0438\u0440\u0443\u0435\u043c 8 \u0431\u0430\u0439\u0442 \u0432 DX         MOVB    DL, BL     \/\/ \u0421\u043e\u0445\u0440\u0430\u043d\u044f\u0435\u043c \u043f\u0435\u0440\u0432\u044b\u0439 \u0441\u0438\u043d\u0438\u0439 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442 \u0432 BL         SHRQ    $32, DX    \/\/ \u0421\u043c\u0435\u0449\u0430\u0435\u043c \u043d\u0430 4 \u0431\u0430\u0439\u0442\u0430         MOVB    DL, BH     \/\/ \u0421\u043e\u0445\u0440\u0430\u043d\u044f\u0435\u043c \u0432\u0442\u043e\u0440\u043e\u0439 \u0441\u0438\u043d\u0438\u0439 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442 \u0432 BH          MOVW    BX, (CX)   \/\/ \u041a\u043e\u043f\u0438\u0440\u0443\u0435\u043c 2 \u0431\u0430\u0439\u0442\u0430 \u0432 dstPaletted          ADDQ    $2, CX         ADDQ    $8, AX          CMPQ    DI, CX         JGT     LOOP         RET<\/code><\/pre>\n<p>\u0418 \u0442\u0443\u0442 \u043c\u0435\u043d\u044f \u0436\u0434\u0430\u043b \u0441\u044e\u0440\u043f\u0440\u0438\u0437, \u044d\u0442\u043e\u0442 \u0432\u0430\u0440\u0438\u0430\u043d\u0442 \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442 \u0441\u0438\u043b\u044c\u043d\u043e \u043c\u0435\u0434\u043b\u0435\u043d\u043d\u0435\u0435 \u043f\u0440\u0435\u0434\u044b\u0434\u0443\u0449\u0435\u0433\u043e:<\/p>\n<pre><code>cpu: AMD Ryzen 7 5800H with Radeon Graphics          BenchmarkCopy BenchmarkCopy-16                      93292    128104 ns\/op BenchmarkCopyAsm-16                   94081    127012 ns\/op BenchmarkCopyAsm1R2W-16              185229     64904 ns\/op BenchmarkCopyAsm1R2WUnrolled-16      240812     49406 ns\/op BenchmarkCopyAsmAcc2-16              155895     76325 ns\/op<\/code><\/pre>\n<p>\u041f\u0440\u0438\u0447\u0451\u043c \u044f \u0441\u043b\u0443\u0447\u0430\u0439\u043d\u043e \u0437\u0430\u043c\u0435\u0442\u0438\u043b, \u0447\u0442\u043e \u0435\u0441\u043b\u0438 \u043d\u0430 \u043f\u0435\u0440\u0432\u043e\u043c \u0448\u0430\u0433\u0435 \u0446\u0438\u043a\u043b\u0430 \u0434\u0435\u043b\u0430\u0442\u044c <code>XORQ BX, BX<\/code>, \u0442\u043e \u0432\u0440\u0435\u043c\u044f \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u044f \u043d\u0435\u043c\u043d\u043e\u0433\u043e \u0443\u043c\u0435\u043d\u044c\u0448\u0430\u0435\u0442\u0441\u044f. \u041d\u043e \u044d\u0442\u043e \u0443\u0436\u0435 \u0448\u0430\u043c\u0430\u043d\u0441\u0442\u0432\u043e.<\/p>\n<p>\u0421\u043b\u0435\u0434\u0443\u044e\u0449\u0430\u044f \u043f\u043e\u043f\u044b\u0442\u043a\u0430 \u0431\u044b\u043b\u0430 \u0441\u043e\u0431\u0440\u0430\u0442\u044c \u0432 \u0440\u0435\u0433\u0438\u0441\u0442\u0440\u0435 BX \u0441\u0440\u0430\u0437\u0443 8 \u0431\u0430\u0439\u0442 \u0438 \u0442\u043e\u043b\u044c\u043a\u043e \u043f\u043e\u0441\u043b\u0435 \u044d\u0442\u043e\u0433\u043e \u0438\u0445 \u0437\u0430\u043f\u0438\u0441\u0430\u0442\u044c \u0432 \u043f\u0430\u043c\u044f\u0442\u044c:<\/p>\n<pre><code class=\"go\">TEXT \u00b7CopyAsmAcc8(SB),$0-48         MOVQ    srcRGBA+0(FP), AX         ADDQ    $2, AX         MOVQ    dstPaletted+24(FP), CX         MOVQ    CX, DI         ADDQ    $512*512, DI  LOOP:   XORQ    BX, BX         MOVQ    (AX), DX         MOVB    DL, BL         SHLQ    $8, BX         SHRQ    $32, DX         MOVB    DL, BL          MOVQ    8(AX), DX         SHLQ    $8, BX         MOVB    DL, BL         SHLQ    $8, BX         SHRQ    $32, DX         MOVB    DL, BL          MOVQ    16(AX), DX         SHLQ    $8, BX         MOVB    DL, BL         SHLQ    $8, BX         SHRQ    $32, DX         MOVB    DL, BL          MOVQ    24(AX), DX         SHLQ    $8, BX         MOVB    DL, BL         SHLQ    $8, BX         SHRQ    $32, DX         MOVB    DL, BL          BSWAPQ  BX           \/\/ \u0411\u0430\u0439\u0442\u044b \u043f\u043e\u043b\u0443\u0447\u0438\u043b\u0438\u0441\u044c \u0432 \u043e\u0431\u0440\u0430\u0442\u043d\u043e\u043c \u043f\u043e\u0440\u044f\u0434\u043a\u0435, \u043f\u043e\u0436\u0442\u043e\u043c\u0443 \u043f\u0435\u0440\u0435\u0432\u043e\u0440\u0430\u0447\u0438\u0432\u0430\u0435\u043c         MOVQ  <\/code><\/pre>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[],"tags":[],"class_list":["post-346316","post","type-post","status-publish","format-standard","hentry"],"_links":{"self":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/346316","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=346316"}],"version-history":[{"count":0,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/346316\/revisions"}],"wp:attachment":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=346316"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=346316"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=346316"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}