CppCon 2017ã«ã³ãã¡ã¬ã³ã¹ã®äžé£ã®ã¬ãã¥ãŒèšäºã®ç¶ãã
ãµã€ã¯ã«ã³ã³ãã³ã ä»åã¯ãCompiler ExplorerïŒ godbolt.org ïŒã®èè
ã«ããéåžžã«è峿·±ããã¬ãŒã³ããŒã·ã§ã³ã§ãã é床ã®ããã«ãã·ããïŒå°ãªããšãx86-64ïŒã§2ãæãããã¹ãŠã®äººã«å¿
ãèªãã§ãã ããã x86-64ã¢ã»ã³ãã©ã«ç²ŸéããŠããå Žåã¯ãäŸïŒãä¹ç®ãããé€ç®ããªã©ïŒãå«ãã»ã¯ã·ã§ã³ã«å·»ãæ»ãããšãã§ããŸãã èè
ã®ãããªãèšèã ç§ã®ã³ã¡ã³ãã¯æäœã®è§æ¬åŒ§ã§å²ãŸããŠããŸãã
ç§ã®ç®æšã¯ãã¢ã»ã³ãã©ãŒãæããªãããšã§ããããã¯äŸ¿å©ãªããšã§ãã ãããŠããã䜿çšããŸããã å¿
ãããåžžã«ã§ã¯ãããŸããã ãããŠãç§ã¯ããªãããã¹ãŠããããŠã¢ã»ã³ãã©ãŒãåŠã¶ã¹ãã ãšèšã£ãŠããã®ã§ã¯ãããŸããã ãã ããã³ã³ãã€ã©ã®çµæã衚瀺ã§ããã¯ãã§ãã ãããŠããããè¡ããšãã³ã³ãã€ã©ãŒãã©ãã ãã®äœæ¥ãè¡ããã©ãã»ã©ã¹ããŒãã§ããããããããŸãã
èæ¯
ãããã£ãŠãèŠçŽããå€å
žçãªæ¹æ³ããããŸãïŒC ++ 11ããåïŒïŒ
int sum(const vector<int> &v) { int result = 0; for (size_t i = 0; i < v.size(); ++i) result += v[i]; return result; }
Range-For-Loopã®åºçŸã«ãããããå¿«é©ãªã³ãŒãã«çœ®ãæããããšãã§ãããã©ããçåã«æããŸããã
int sum(const vector<int> &v) { int result = 0; for (int x : v) result += x; return result; }
ç§ãã¡ã®ææã¯ãä»ã®èšèªã®ã€ãã¬ãŒã¿ã«ãã§ã«åãŸããŠãããšããäºå®ã«é¢é£ããŠããŸããã ã€ãã¬ãŒã¿ãæ§ç¯ãããã³ã³ãããå埩åŠçããçµéšããããã¬ããŒãžã³ã¬ã¯ã¿ã«äœæ¥ã远å ãããŸããã ããã¯C ++ã«ã¯åœãŠã¯ãŸããªãããšãããã£ãŠããŸãããã確èªããå¿
èŠããããŸããã
èŠå
ã¢ã»ã³ããªã³ãŒãã®èªã¿åãïŒããã§äœãèµ·ãã£ãŠããããèŠãããšãã§ããæç€ºãå°ãªãããã«ãããããéãåäœãããšèãããšãç°¡åã«ã ãŸãããå¯èœæ§ããããŸãã çŸä»£ã®ããã»ããµã§ã¯ãéåžžã«è€éãªããšãèµ·ãããäºæž¬ã§ããŸããã ããã©ãŒãã³ã¹ãäºæž¬ããå Žåã¯ãåžžã«ãã³ãããŒã¯ãå®è¡ããŠãã ããã ããšãã°ãGoogleãŸãã¯ãªã³ã©ã€ã³ãªã³ã©ã€ã³http://quick-bench.comãã ã
X86-64ã¢ã»ã³ãã©ãŒã®åºæ¬
ç»é²
- 16æŽæ°64ãããæ±çšã¬ãžã¹ã¿ãŒïŒRAXãRBXãRCXãRDXãRBPãRSIãRDIãRSPãR8-R15ïŒ
- 8ã€ã®80ãããæµ®åå°æ°ç¹ã¬ãžã¹ã¿ãŒïŒST0-ST7ïŒ
- 16åã®128ãããSSEã¬ãžã¹ã¿ïŒXMM0-XMM15ïŒ
ABI颿°ãåŒã³åºãããã®èŠåããããŸã ãããã¯ãç¹ã«ã颿°ãçžäºã«ãéä¿¡ãããæ¹æ³ã§ãã
- rdiãrsiãrdx-åŒæ°
- rax-æ»ãå€
ãŸããã©ã®ã¬ãžã¹ã¿ãäžæžãã§ããããã©ã®ã¬ãžã¹ã¿ãä¿æããããšããã«ãŒã«ããããŸãã ãã ããã¢ã»ã³ãã©ãŒã§èšè¿°ããªãå Žåã¯ãããããç¥ãå¿
èŠã¯ãããŸããã

æ±çšã¬ãžã¹ã¿ã¯64ãããã§ãããååã¯ç°ãªããŸãã ããšãã°ãeaxã¬ãžã¹ã¿ãåç
§ãããšãraxã¬ãžã¹ã¿ã®äžäœ32ããããååŸãããŸãã ãã ããè€éãªçç±ã«ãããeaxã«æžã蟌ããšraxã®äžäœ32ãããããªã»ãããããŸãïŒçç±ïŒ ã ããã¯ã,ããããã¢ã«ã«ã¯é©çšãããŸããã
éå¶
Intelæ§æã䜿çšããŠããŸã ã éšå±ã§Intelæ§æã䜿çšããã®ã¯èª°ã§ããïŒ ATïŒTã¯ã©ãã§ããïŒ ããã仿¥ã¯èªåã®ããã«æµãäœã£ãããã§ãã
æäœã®çš®é¡ïŒIntelæ§æïŒïŒ
op op dest op dest, src op dest, src1 src2
ããŒã¢ããã¯ã³ãŒãïŒopïŒã®äŸïŒcallãretãaddãsubãcmpã ãªãã©ã³ãïŒdestãsrcïŒã¯ã次ã®åœ¢åŒã®ã¬ãžã¹ã¿ãŸãã¯ã¡ã¢ãªåç
§ã§ãã
[base + reg1 + reg2 * (1, 2, 4 or 8)]
ã¡ã¢ãªåç
§ã絶察å€ã«ãªãããšã¯ãã£ãã«ãããŸããã ã¬ãžã¹ã¿ã®å€ã䜿çšããã ãã§ãªããå¥ã®ã¬ãžã¹ã¿ã®å€ã§æå®ããããªãã»ããã远å ããããšãã§ããŸãã
äŸãèããŠã¿ãŸãããïŒ
mov eax, DWORD PTR [r14] add rax, rdi add eax, DWORD PTR [r14+4] sub eax, DWORD PTR [r14+4*rbx] lea rax, [r14+4*rbx] xor edx, edx
åœŒã®æ¬äŒŒã³ãŒãïŒ
int eax = *r14;
è¡ãåæããŸãããïŒ
- r14ã¬ãžã¹ã¿ãã4ãã€ããèªã¿åããeaxã«é
眮ããŸãã
- RDIå€ãraxã«è¿œå ããŸãã
- r14 + 4ã«ä¿åããã4ãã€ãã®å€ãeaxã«è¿œå ããŸãã ãã®ãããªã¡ã¢ãªã¢ã¯ã»ã¹ã¯ãr14ã4ãã€ãæ°ã®é
åã®å
é ãžã®ãã€ã³ã¿ã§ããå Žåãæåã®ïŒãŒãããã«ãŠã³ãããïŒé
åå€ãååŸããããšã«äŒŒãŠããŸãã
- åã®ãã®ãšäŒŒãŠããŸãããé
åã®ã€ã³ããã¯ã¹ã倿Žã§ããŸãã
- leaã³ãã³ãã¯ãå®å¹ã¢ãã¬ã¹ãããŒãããããã«äœ¿çšãããŸãã [
mov rax, r14+4*rbx
ãããªãã®ããããæžãããŠããã° ã] - ããã«ãªã»ãããããããªå¥åŠãªæ¹æ³ããããŸãã å®éã
mov edx, 0
ã¯4ãã€ãã xor edx, edx
ã¯2ãã€ãã䜿çšããŸãã
ã³ã³ãã€ã©ãšã¯ã¹ãããŒã©ãŒv0.1
ãŸããã³ã³ãã€ã©ãŒã®åäœã調ã¹ãããã«ã次ã®ããšãè¡ããŸããã ã³ãã³ãã«ãã£ãŠã³ã³ãã€ã«ãããŸãïŒ
$ g++ /tmp/test.cc -O2 -c -S -o - -masm=intel \ | c++filt \ | grep -vE '\s+\.'
説æ
g++
å®è¡ïŒ
- ã³ã³ãã€ã«test.cc
- æé©åãæå¹ã«ããå ŽåïŒ-O2ïŒ
- ãªã³ã«ãŒãåŒã³åºããã«ïŒ-cïŒ
- ã¢ã»ã³ããªãŒã»ãªã¹ãçæïŒ-SïŒ
- æšæºã¹ããªãŒã ãžã®åºåïŒ-o-ïŒ
- Intel衚èšã䜿çšïŒ-masm = intelïŒ
c++filt
filt-ååãã³ãŒããŠãŒãã£ãªãã£ïŒããã³ã°ã«ïŒãgrep -vE '\s+\.'
-ãã¹ãŠã®é¢çœãè¡ãåé€ããŸãã
ç£èŠãŠãŒãã£ãªãã£ã䜿çšããŠäžå®ã®ééã§ãã®ã³ãã³ããå®è¡ãã -d
ïŒdiffïŒãã©ã°ãèšå®ããŠå·®åã衚瀺ããŸããã æ¬¡ã«ã tmuxã䜿çšããŠç«¯æ«ãååã«åå²ããäžæ¹ã«ã¹ã¯ãªãããé
眮ãã仿¹ã«viãé
眮ããŸããã ãããŠãç§ã¯ã³ã³ãã€ã©ãšã¯ã¹ãããŒã©ãæã«å
¥ããŸããã
ã³ã³ãã€ã©ãšã¯ã¹ãããŒã©ãŒ
Compiler Explorerã®ææ°ããŒãžã§ã³ã«ã€ããŠç°¡åã«èª¬æããŸãã ã³ãŒãã§æ°ãããŠã£ã³ããŠãäœæããã«ã¯ãããšãã£ã¿ãŒããã¯ãªãã¯ããŠãå¿
èŠãªå Žæã«ãã©ãã°ããŠãã©ãã°ããå¿
èŠããããŸãã ã³ã³ãã€ã«çµæãå«ããŠã£ã³ããŠãäœæããã«ã¯ãäžç¢å°ã®ãã¿ã³ãã¯ãªãã¯ããŠæŒãããŸãŸãã©ãã°ããŸãã é»è²ã®ç·ã«ã«ãŒãœã«ãåããããšãã¢ã»ã³ãã©ãŒéšåã®å¯Ÿå¿ããç·ã倪ããªããŸãã
ãªã³ã¯

åŒæ°-O2 -std=c++1z -march=haswell
ããŠGCC 7.1ãéžæã-O2 -std=c++1z -march=haswell
ã int result = 0;
xor eax eax
察å¿ããŸãã rdxã¬ãžã¹ã¿ã«ã¯ããã¯ã¿ãŒã®çŸåšã®èŠçŽ ãžã®ãã€ã³ã¿ãŒãå«ãŸããŠããŸãã 环ç©result += x;
rdxã®ã¢ãã¬ã¹ã«ããå€ã ãeax
ã¬ãžã¹ã¿ã®å€ãå¢ããããã®åŸã®é
åã®æ¬¡ã®èŠçŽ ãžã®ç§»è¡ãšããŠå®è£
ãããŸãã æååãreturn result;
ãã€ã©ã€ããããŠããŸãããã€ãŸããæç€ºçã«äžèŽãããã®ã¯ãããŸããã ããã¯ãã«ãŒããçµäºããåŸãeaxã¬ãžã¹ã¿ïŒæ»ãå€ãæ ŒçŽããããã«ãã䜿çšãããïŒã«æ¢ã«å€ãå«ãŸããŠããããã§ãã æé©åã«ãããã³ã³ãã€ã©ãŒã¯ç§ãã¡ãèŠæ±ãããšããã«ãªããŸããã
次ã«ãæé©åãªãã§ã³ã³ãã€ã«çµæã衚瀺ããŸãïŒ-O0ïŒã

-O1
ã§ã³ã³ãã€ã«ããå ŽåãGCCã¯äœããã®çç±ã§mov eax, 0
代ããã«xor eax, eax
ã䜿çšããå¿
èŠããããšã¯èããŸããã
-O3
倿Žã-O3
ã ããã¯é©ãã¹ãããšã§ããèŠãŠã¿ãŸãããïŒ

ã¯ãœãããããã¹ãŠã®ã¯ãŒã«ãªæäœã䜿çšãããŠããŸãïŒ ãã ãããã®ãããªã³ãŒããåçŽãªããŒãžã§ã³ãããé«éã§ããããšã確èªããã«ã¯ããã³ãããŒã¯ã䜿çšããå¿
èŠããããŸãã
äŸã«æ»ããŸãããã
ã³ãŒãä»ãã®2ã€ã®ãŠã£ã³ã㊠ïŒ

æ¯èŒïŒdiffïŒ ïŒ

å·ŠåŽã«ã¯0ãããµã€ãºãŸã§ã®ãµã€ã¯ã«ããããå³åŽã«ã¯ç¯å²ããããŸãã ã«ãŒããå®è£
ããã³ãŒãã¯ãã©ã¡ãã®å Žåãåãã§ãã ãã®æ¹æ³ã詊ããŠã¿ãŸãããïŒ
int sum(const vector<int> &v) { return std::accumulate(std::begin(v), std::end(v), 0); }
åãããšã
詳现åæ
æåã®2è¡ããå§ããŸãããã
; rdi = const vector<int> * mov rdx, QWORD PTR [rdi] ; rdx = *rdi â¡ begin() mov rcx, QWORD PTR [rdi+8] ; rcx = *(rdi+8) â¡ end()
åç
§ã«ãããã¯ãã«ãæž¡ããŸããã ãããããªã³ã¯ã®ãããªãã®ã¯ãããŸããã ãã€ã³ã¿ãŒã®ã¿ã rdiã¬ãžã¹ã¿ã¯ãéä¿¡ããããã¯ãã«ã瀺ããŸãã å€ã¯ã¢ãã¬ã¹rdiããã³rdi + 8ã§èªã¿åãããŸããrdiãinté
åãžã®çŽæ¥ã®ãã€ã³ã¿ãŒã§ãããšèããã®ã¯èª€ãã§ãã ããã¯ããã¯ã¿ãŒãžã®ãã€ã³ã¿ãŒã§ãã å°ãªããšãGCCã§ã¯ããã¯ã¿ãŒã®å®è£
ã¯æ¬¡ã®ãšããã§ãã
template<typename T> struct _Vector_impl { T *_M_start; T *_M_finish; T *_M_end_of_storage; };
ã€ãŸãããã¯ãã«ã¯3ã€ã®ãã€ã³ã¿ãŒãå«ãæ§é ã§ãã æåã®ãã€ã³ã¿ãŒã¯é
åã®å§ãŸãã2çªç®ã¯çµããã3çªç®ã¯ãã®ãã¯ãã«ã®äºçŽæžã¿ã¡ã¢ãªãŒïŒå²ãåœãŠæžã¿ïŒã®çµããã§ãã é
åã®ãµã€ãºã¯ããã«æç€ºçã«ä¿åãããŸããã ããã¯é¢çœãã§ãã ãµã€ã¯ã«ã®éå§åã«å®è£
ã®éããèŠãŠã¿ãŸãããã æåã®äŸïŒã€ã³ããã¯ã¹ä»ãã®éåžžã®ã«ãŒãïŒïŒ
sub rcx, rdx ; rcx = end-begin mov rax, rcx shr rax, 2 ; (end-begin)/4 je .L4 add rcx, rdx xor eax, eax
æåã®è¡ã¯ãé
åã®ãã€ãæ°ãèšç®ããŸãã 3çªç®ã§ã¯ããã®å€ã4ã§å²ã£ãŠèŠçŽ ã®æ°ãèŠã€ããŸãïŒintã¯4ãã€ãã§ããããïŒã ã€ãŸããåãªããµã€ãºé¢æ°ã§ãã
size_t size() const noexcept { return _M_finish - _M_start; }
ã·ããæäœåŸã«ãµã€ãº0ãååŸããå ŽåãEqual Flagãèšå®ãããç§»è¡æäœje
ïŒJump If EqualïŒãããªã¬ãŒãããããã°ã©ã ã¯0ãè¿ããŸãããããã£ãŠããµã€ãºããŒããã©ããããã§ãã¯ããŸããã ããã«ãå埩äžã«ããµã€ãºãæå®ããã€ã³ããã¯ã¹ãã§ãã¯ãå®è¡ããããšæ³å®ããŠããŸãã ããããã³ã³ãã€ã©ã¯å®éã«ãã®ã€ã³ããã¯ã¹ãå¿
èŠãšããªããšæšæž¬ããã«ãŒãå
ã§é
åèŠçŽ ãžã®çŸåšã®ãã€ã³ã¿ãšé
åã®æåŸïŒrcxïŒãæ¯èŒããŸãã
次ã«ã2çªç®ã®äŸïŒç¯å²ä»ãïŒïŒ
xor eax, eax cmp rdx, rcx ; begin==end? je .L4
éå§ãã€ã³ã¿ãçµäºãšçãããã©ãããåçŽã«æ¯èŒããçããå Žåã¯ããã°ã©ã ã®æåŸã«ãžã£ã³ãããŸãã å®éãããã¯èµ·ãããŸããïŒ
auto __begin = begin(v); auto __end = end(v); for (auto __it = __begin; __it != __end; ++it)
ãµã€ã¯ã«èªäœã¯äž¡æ¹ã®å Žåã§åäžã§ãïŒ
; rcx â¡ end, rdx = begin, eax = 0 .L3: add eax, DWORD PTR [rdx] ; eax += *rdx add rdx, 4 ; rdx += sizeof(int) cmp rdx, rcx ; is rdx == end? jne .L3 ; if not, loop ret ; we're done
ç§ãã¡ã¯èŠã€ããŸããïŒ
- Range-forã®æ¹ãè¥å¹²åªå
ããããªãã·ã§ã³ã§ããããšã倿ããŸããã
- ã³ã³ãã€ã©ãªãã·ã§ã³ã¯éèŠã§ãã
- std :: collectã¯åãçµæã瀺ããŸãã
ä¹ç®
次ã«ãå°ãããªãããã¯ãŒã«ãªäŸã瀺ããŸãã
int mulByY(int x, int y) { return x * y; }
mulByY(int, int): mov eax, edi imul eax, esi ret
ediã¯æåã®ãã©ã¡ãŒã¿ãŒãesiã¯2çªç®ã®ãã©ã¡ãŒã¿ãŒã§ãã imulã䜿çšããéåžžã®ä¹ç®ââã ããã¯ã4ãããã®æåä¹ç®ã®ããã§ãã
1101 (13) x 0101 (5) -------- 1101 0000 1101 + 0000 -------- 01000001 (65)
4ã€ã®è¿œå ãå®äºããå¿
èŠããããŸããã Haswellã§ã¯ã32ãããã®ä¹ç®ãããã4ã¯ããã¯ãµã€ã¯ã«ã§å®è¡ãããã®ã¯å¥è·¡ã§ãã 1ãã£ãã¯ã®è¿œå ã ããããããã«é«éãªäŸãèŠãŠã¿ãŸãããã
int mulByConstant(int x) { return x * 2; }
1ã®å·Šã·ãããçºçããããšãäºæ³ãããŸãã
lea eax, [rdi+rdi]
1ã€ã®æäœã leaã®å©ç¹ã¯ããœãŒã¹ãéåžžã«æè»ã«èšå®ã§ããããšã§ãã ã·ããã䜿çšããŠå®è£
ããã«ã¯ãå€ãeaxã«ã³ããŒããŠã·ãããããšãã2ã€ã®æäœãè¡ãå¿
èŠããããŸãã
int mulByConstant(int x) { return x * 4; }
lea eax, [0+rdi*4]
leaã¯ã2ã4ã8ã«ããä¹ç®ããµããŒãããŸãããããã£ãŠã8ã«ããä¹ç®ã¯åæ§ã«ãªããŸãã
lea eax, [0+rdi*8]
ãã§ã«ã·ããããŠãã16æ³ãŸã§ã«ïŒ
mov eax, edi sal eax, 4
65599ã§ïŒ
imul eax, edi, 65599
ããããããã®ã³ã³ãã€ã©éçºè
ã¯æã£ãŠããã»ã©è³¢ããããŸããã ããå¹ççã«å®è£
ã§ããŸãïŒ
int mulBy65599(int a) { return (a << 16) + (a << 6) - a;
ç§ãã¡ã¯ãã§ãã¯ããŸãïŒ
imul eax, edi, 65599
ããïŒ [ ç¬ããææ ]ã ããã¯äœã§ãããã³ã³ãã€ã©ã¯ç§ãããè³¢ãã§ããïŒ ã¯ãã確ãã«ãä¹ç®ã¯ãããã®å°æ°ã®ã·ããããã³å ç®ããã广çã§ãã ããããããã¯ææ°ã®ããã»ããµäžã«ãããŸãã æéãé¡ã£ãŠã¿ãŸããã-O2 -std=c++1z -march=i486 -m32
ïŒ
mov edx, DWORD PTR [esp+4] mov eax, edx sal eax, 16 mov ecx, edx sal ecx, 6 add eax, ecx sub eax, edx
ããŠã return a * 65599;
ãŸãããreturn a * 65599;
ïŒ
mov edx, DWORD PTR [esp+4] mov eax, edx sal eax, 16 mov ecx, edx sal ecx, 6 add eax, ecx sub eax, edx
ã³ã³ãã€ã©ãŒã«ããããã¹ãŠã®åæ§ã®ããšããããŠãã ããã
éšé
äžè¬çãªå ŽåïŒ
int divByY(int x, int y) { return x / y; }
divByY(int, int): mov eax, edi cdq idiv esi ret
Haswellã§ã¯ã32ãããé€ç®ã¯22ã29ãµã€ã¯ã«ã§å®è¡ãããŸãã ãã£ãšè¯ãã§ããŸããïŒ
unsigned divByConstant(unsigned x) { return x / 2; }
mov eax, edi shr eax
éæ³ã§ã¯ãªããå³ãžã®ã·ããã§ãã ãŸãã4ã8ã16ãªã©ã§å²ã£ãŠãé©ãããšã§ã¯ãããŸããã3ã詊ããŠã¿ãŸãããã
mov eax, edi mov edx, -1431655765 mul edx mov eax, edx shr eax
ã©ããã
mov eax, edi ; eax = x mov edx, 0xaaaaaaab mul edx ; eax:edx = x * 0xaaaaaaab mov eax, edx ; (x * 0xaaaaaaab) >> 32 ; â¡ (x * 0xaaaaaaab) / 0x10000000 ; â¡ x * 0.6666666667 shr eax ; x * 0.333333333 ret
2/3 * xã«çããå€ã¯ãedx-64ãããä¹ç®çµæã®äžäœ32ãããã§ããããšã倿ããŸããã ã€ãŸããå®éã«ã¯ã2/3ã®ä¹ç®ãšå³ãžã®1ã®ã·ããããããŸããã [ ã¯ã£ããããŠããªãå Žåã¯ã16鲿°ã®èšç®æ©0xaaaaaaabã§3ã4ã5ã6ãæããŠãäžäœæ¡ã確èªããŠãã ãã]ã
é€ç®ã®æ®ã
äžè¬çãªå ŽåïŒ
int modByY(int x, int y) { return x % y; }
modByY(int, int): mov eax, edi cdq idiv esi mov eax, edx ret
ç¹ã«ã3ã§å²ã£ãæ®ãã®éšåïŒ
int modBy3(unsigned x) { return x % 3; }
mov eax, edi mov edx, 0xaaaaaaab mul edx mov eax, edx shr eax lea eax, [rax+rax*2] sub edi, eax mov eax, edi
æåã®5è¡ã¯ããã§ã«æ€èšãããŠããéšéã§ãã 以äžã§ã¯ãé€ç®çµæã«3ãæããŠãå
ã®å€ããæžç®ããŸãã ã€ãŸããx-3 * [x / 3]ã ã¢ãžã¥ãé€ç®ã«æ³šæãæãã®ã¯ãªãã§ããïŒ ããã·ã¥ãããã§äœ¿çšãããŠãããã-ãã¹ãŠã®äººã«æãããŠããã³ã³ããã ãªããžã§ã¯ããæ€çŽ¢ãŸãã¯ã³ã³ããã«è¿œå ããããã«ãããã·ã¥ãããã·ã¥ããŒãã«ã®ãµã€ãºã§å²ã£ãäœããèšç®ãããŸãã ãã®æ®ãã¯ãããŒãã«èŠçŽ ïŒãã±ããïŒã®ã€ã³ããã¯ã¹ã§ãã ãã®æäœãã§ããã ãæ©ãæ©èœããããšãéåžžã«éèŠã§ãã äžè¬çã«ãããã¯ããªãé·ãéæ©èœããŸãã ãããã£ãŠãlibc ++ã¯æå¹ãªããŒãã«ãµã€ãºã«2ã®ã¹ãä¹ã䜿çšããŸãã ãããããããã¯ããŸãè¯ãå€ã§ã¯ãããŸããã Boost multi_indexã®å®è£
ã«ã¯ãå€ãã®æå¹ãªãµã€ãºãšãããããªã¹ãããã¹ã€ãããå«ãŸããŠããŸãã
[ èŽè¡ããã®è³ªåãã倿ãããšã誰ãããã®èª¬æãçè§£ããããã§ã¯ãããŸããã 倧ãŸãã«èšããšããã®ãããªå®è£
ã¯æ¬¡ã®ãšããã§ãã ]
switch(size_index): { case 0: return x % 53; case 1: return x % 97; case 2: return x % 193; ... }
ãããæ°
次ã®é¢æ°ã¯ãåäžããããã«ãŠã³ãããŸãã
int countSetBits(int a) { int count = 0; while (a) { count++; a &= (a-1); } return count; }
åå埩ã§ãæãè¥ããŠãããã®çªå·ã¯ãæŽæ°ããŒãã«ãªããŸã§æ¶ããŸãã GCCã¯å·§åŠã«è¡ããŸããïŒ
countSetBits(int): xor eax, eax test edi, edi je .L4 .L3: add eax, 1 blsr edi, edi test edi, edi jne .L3 ret .L4: ret
ããã§ãåŒa &= (a-1);
blsr
åœä»€ã«çœ®ãæããããŸããã ãã®å
¬æŒã®æºåãããåã«ç§ã¯åœŒå¥³ã«äŒã£ãããšããããŸããã§ããã æåŸã®ãŠããããã¯ãªã¢ããæå®ãããã¬ãžã¹ã¿ã«çµæãå
¥ããŸãã å¥ã®ã³ã³ãã€ã©ãéžæããŠã¿ãŸãããx86-64 clang (trunk)
ïŒ
popcnt eax, edi
ããã¯ãã€ã³ãã«ã远å ããã»ã©å€ãã®äººãæãã§ãããããã«ãŠã³ãåœä»€ã§ãã clangãå®è¡ããå¿
èŠããããšèããŠãã ããã 圌ã«ã¯ãããããæ°ãããããšããæãããã¯ãããŸããã§ããã
远å
0ããxãŸã§ã®ãã¹ãŠã®æŽæ°ã®å ç®ïŒ
constexpr int sumTo(int x) { int sum = 0; for (int i = 0; i <= x; ++i) sum += i; return sum; } int main(int argc, const char *argv[]) { return sumTo(20); }
mov eax, 210
ããããŸãã ããã§constexprã¯ããã»ã©éèŠã§ã¯ãããŸããã ãããstatic [ 颿°ã1ã€ã®ç¿»èš³åäœã§ã®ã¿è¡šç€ºãããããã« ]ã«çœ®ãæãããšãåãçµæãåŸãããŸãã sumTo(argc)
ãåŒã³åºããšãã«ãŒãã¯ã©ãã«ãè¡ããŸããã clangã詊ããŠã¿ãŸãããã
test edi, edi js .LBB0_1 mov ecx, edi lea eax, [rdi - 1] imul rax, rcx shr rax add eax, edi ret .LBB0_1: xor eax, eax ret
è峿·±ãããšã«ããµã€ã¯ã«ã¯ãªããªããŸããã æåã®2è¡ã¯åŒæ°ã®ãŒãããã§ãã¯ããŸãã æ¬¡ã®5ã¯åçŽãªåèšåŒã§ãïŒxïŒx + 1ïŒ/ 2 == x + xïŒx-1ïŒ/ 2ã INT_MAXãæž¡ãããå Žåãæåã®ããŒãžã§ã³ã¯ãªãŒããŒãããŒãåŒãèµ·ãããããåŒã®2çªç®ã®ããŒãžã§ã³ãå®è£
ãããŸãã
Compiler Explorerã®ä»çµã¿
[ èè
ã話ããããã«ãããã³ããšã³ããDockerãä»®æ³åãªã©ãçè§£ããŠããªããããæãããææ§ã«ããªãããã«ãå®è£
ã®åŸ®åŠãªç¹ããã¹ãŠèª¬æããªãããšã«ããŸãã ]
node.jsã§èšè¿°ãããŠããŸãã Amazon EC2ã§èµ·åããŸããã ããã¯ãã®äŒè°ã§ã®2åç®ã®ã¹ããŒãã§ãJavaScriptã«ã€ããŠè©±ãããšãŠãæ°åãæªãã§ãã ãã¡ãããC ++ãæ¹å€ããããšããããŸã...ããããJavaScriptã ããèŠããšããã...
ãã¹ãŠæ¬¡ã®ããã«ãªããŸãã
function compile(req, res, next) { // exec compiler, feed it req.body, parse output } var webServer = express(); var apiHandler = express.Router(); apiHandler.param('compiler', function (req, res, next, compiler) { req.compiler = compiler; next(); }); apiHandler.post('/compiler/:compiler/compile', compile); webServer.use('/api', apiHandler); webServer.listen(10240);
Amazon EC2
æ¬¡ã®æ©èœïŒ
- ãšããžãã£ãã·ã¥
- ããŒããã©ã³ãµãŒ
- ä»®æ³ãã·ã³
- Dockerã€ã¡ãŒãž
- å
±æã³ã³ãã€ã©ã¹ãã¬ãŒãž
ã³ã³ãã€ã©ãŒ
apt-getã䜿çšããŠã€ã³ã¹ããŒã«ããŸããã Microsoftã³ã³ãã€ã©ã¯WINEãä»ããŠåäœããŸãã
å®å
šæ§
倧ããªã»ãã¥ãªãã£ããŒã«ã ã³ã³ãã€ã©ã¯å®è¡ããã®ã§ã¯ãªãã³ã³ãã€ã«ããã ãã§ãããããšãã°GCCã¯ãã©ã°ã€ã³ããµããŒãããŠãããåçã©ã€ãã©ãªïŒ -fplugin=/path/to/name.so
ïŒãããŒãã§ããŸãã ãŸãã¯specsãã¡ã€ã«ã æåã¯æœåšçãªè匱æ§ãèŠã€ããããšããŸãããããã¹ãŠãèæ
®ããããšã¯éåžžã«é£ãããšããçµè«ã«éããŸããã ãããŠãç§ã¯ãèµ·ããããææªã®äºæ
ãšã¯äœã§ããïŒ Dockerã³ã³ããã忢ã§ããŸãããåã³èµ·åããŸãã ä»®æ³ãã·ã³ã®å€ã«åºãŠããç¹æš©ã¯ãããŸããã Dockerã¯ãã®ãããªããªãã¯ããç§ãå®ããŸãã
ããã³ããšã³ã
Microsoft Monacoã¯ããªã³ã©ã€ã³ã³ãŒããšãã£ã¿ãŒãšããŠäœ¿çšãããŸãã ãŠã£ã³ããŠã®ãã©ãã°ããããã¯ãGoldenLayoutã䜿çšããŠå®è£
ãããŸãã
ãœãŒã¹ã³ãŒã
è¿æ¥å
Ž
- CFG-ã³ã³ãããŒã«ã°ã©ããã¥ãŒã¢[ IDAã®ããã«ãç§ãçè§£ããŠããããã« ]ã
- èšèªã®çµ±äžã Compiler Explorerã¯ä»ã®èšèªïŒ{dãswiftãhaskellãgoãispc} .godbolt.orgïŒããµããŒãããŠããŸãã ç°ãªããã¡ã€ã³ã§ã¯ãªãã1ã€ã®å Žæã§ããããçµåããããšæããŸãã ç°ãªãèšèªã§ã®åãå®è£
ãæ¯èŒã§ããããã«ã
- ã³ãŒããå®è¡ããŠããŸãïŒ
ã質å
Boostãªã©ãä»ã®ã©ã€ãã©ãªã®ãµããŒããåžæããŸãã
ãã§ã«ããã€ããããŸãïŒ

Boost multi_indexã§å¯èœãªãã¹ãŠã®ããŒãã«ãµã€ãºã®åãæ¿ãã«ã€ããŠèª¬æããŸããã ãã ãããã®ãããªå®è£
ã¯éå¹ççã§ããå€ãéåžžã«ãŸã°ããªã®ã§ããžã£ã³ãããŒãã«ã䜿çšããã®ã§ã¯ãªãããã€ããªæ€çŽ¢ã®ã¿ã䜿çšããŸãã
ã¹ã€ããã¯ãµã€ãºèªäœããªã¹ãããŸããããã€ã³ããã¯ã¹ããªã¹ãããŸãã
Webã¢ã»ã³ããªããµããŒãããäºå®ã§ãã
Webã¢ã»ã³ããªçšã®ããã¯ãšã³ãããªãå€ãã®ã³ã³ãã€ã©ããããŸãã ãŸããã¯ããããã¯ããã§ãããããä»ã®ãã®ã§å¿ããéã
è²»çšã¯ãããã§ããïŒ
ç§ã¯AmazonãµãŒããŒã«æã«çŽ120ã150ãã«ãè²»ãããŠããŸãã
llvmäžé衚çŸã®ãµããŒãã¯äºå®ãããŠããŸããïŒ
ã¯ãã -emit-llvm
ãã©ã°ã-emit-llvm
ããŠå®è¡ããå Žåããã§ã«ååšããŸãã ã³ã³ãã€ã©èªäœããã®ãã³ããçæããŸãããç§ã¯äœãããŸããã ããã¯ã©ã€ãã®æ¹åãèšç»ãããŠããŸãã
ãœãŒã¹ã³ãŒããšã¢ã»ã³ãã©ãŒã³ãŒãã®å¯Ÿå¿ããè¡ãã©ã®ããã«è²ä»ãããŸããïŒ
ã-gããã©ã°ãæå®ããŠå®è¡ããã ãã§ãã çµæã®ãªã¹ãã«ã¯ãè¡çªå·ä»ãã®ã³ã¡ã³ããå«ãŸããŠããŸãã