Goèšèªã¯æè¿ãããã§ç¹°ãè¿ãè°è«ãããŠããŸããã æ¹å€ãã ã è³è³ãããŸãã ã Intelã®ç§ãã¡ã¯GoãæããŠããããã®ãããžã§ã¯ãã®ãªãŒãã³ãœãŒã¹éçºã«é¢äžããŠããŸãã Goã䜿çšããŠããå Žåããã®ãã°ãããèšèªã§æãå¹æçãªããã°ã©ãã³ã°ã®å éšæ§é ãšåé¡ã«èå³ããããªããcatã«ããããã ãã®èšäºã§ã¯ãGoãå€éšåŒã³åºãã¡ã«ããºã ãå®è£ ããæ¹æ³ãšããããã©ã®ãããé«éã«åäœãããã«ã€ããŠèª¬æããŸãã
goã®äœæè ãèšèªãèšèšãããšãã«åŸãäž»ãªååã¯ããã®ãããžã§ã¯ããç·šæããããšã®æ倧ã®ã·ã³ãã«ãã§ãã äœæè ã¯ãããã©ã«ããã§äœ¿çšå¯èœãªããªãŒããŒããŒããããã³éå°ãªæ©èœãæå³çã«åé¿ãããããè¿œå ã®æ©èœã¯ãã¹ãŠãèšèªãŠãŒã¶ãŒãå¿ èŠã«å¿ããŠã€ã³ã¹ããŒã«ã§ãããŠãŒãã£ãªãã£ã«ãªããŸãã ãããã£ãŠãGoã¯åãªããã©ãããã©ãŒã ã§ã¯ãªããæçšãªæšæºãŠãŒãã£ãªãã£ã®ã»ããã§ããããŸãã Goèªäœã«ã¯æäœéå¿ èŠãªãã®ã ããå«ãŸããŠããŸãããèšèªã®äœæè ã«ãã£ãŠæäŸãããããŸãã¯ã³ãã¥ããã£ã«ãã£ãŠäœæãããéåžžã«å€ãã®è¿œå ã®äŸ¿å©ãªããŒã«ãåžžã«å©çšå¯èœã§ãã ããšãã°ãæšæºãŠãŒãã£ãªãã£ã«ã¯go vetããããŸããããã¯ãã³ãŒãå ã®çãããæ§é ããã£ããããã®ã«åœ¹ç«ã¡ãŸãïŒããã«go lint ã errcheck ã structcheckãªã©ãã€ã³ã¹ããŒã«ã§ããŸãïŒã ãã¹ããŠãŒãã£ãªãã£ã¯ãããã±ãŒãžã®ãã¹ãã ä¿®æ£ãèªååããŸã-Goã®æ°ããããŒãžã§ã³ãšå€æŽãããAPIãžã®ç§»è¡ãæ¯æŽããæ¢åã®ã³ãŒãã«å¿ èŠãªå€æŽãå ããŸãã Goã®äœæè ã¯ããããã®ããŒã«ã®å©äŸ¿æ§ãšäœ¿ããããã®é¢åãã¿ãŠããããã®ãããã§ã³ãŒããæžãããšã¯ç°¡åã§æ¥œããã¿ã¹ã¯ã«ãªããŸãã
ãšããããäœæè ã¯Goããã°ã©ã ã§Cã©ã€ãã©ãªã䜿çšããå¯èœæ§ãæäŸããŸãã ããã¯éåžžã«éèŠã§ããçŸæç¹ã§ã¯ãGo-shnyããã±ãŒãžã¯ãã¹ãŠã®å Žåã«ååšããããã§ã¯ãªããã»ãšãã©ãã¹ãŠãCã§å®è£ ãããŠããããã§ãã Goã§ãã®è±å¯ãªCã©ã€ãã©ãªããã¹ãŠäœ¿çšããããã«ãcgoãŠãŒãã£ãªãã£ãäœæãããŸããã Goã³ãŒããåæããå¿ èŠã«å¿ããŠGoããã°ã©ã ãã³ã³ãã€ã«ãããšãã«ãæå®ããããã©ã°ã䜿çšããŠæ¥ç¶ãããCã³ãŒãã®Cã³ã³ãã€ã©ãåŒã³åºããCãã¡ã€ã«ãšGoãã¡ã€ã«ãã1ã€ã®ããã±ãŒãžã圢æããŸãã ãã®å©ãã«ãããCã³ãŒãã¯Goã«éåžžã«ç°¡åã«çµ±åã§ããŸãïŒããšãã°ã ãã¡ããåç § ïŒ
ããããCã³ãŒã«ãç©æ¥µçã«äœ¿çšããGoã³ãŒãã¯ã©ã®çšåºŠå¹ççã«æ©èœããã®ã§ããããïŒ ãããç解ããã«ã¯ãGoã©ã³ã¿ã€ã ã®å éšã¡ã«ããºã ã«ã€ããŠããå°ãåŠã¶å¿ èŠããããŸãã ä»åŸãCã³ãŒã«ã®æå¹æ§ãçããããã«åæãè¡ãããšãã§ããããã«ãªãããããã®ç¥èãå¿ èŠã ãšèšããŸãã
ã©ã³ã¿ã€ã ã®ä»çµã¿
Goã«ã¯goroutineããããŸã-ãããã¯ãŠãŒã¶ãŒã¬ãã«ã®ãå®è¡ã®ã¹ã¬ãããã§ã-go-routineã¯1ã€ã®ã·ã¹ãã ã¹ã¬ããã®ãã¬ãŒã ã¯ãŒã¯å ã§åãæ¿ãããããããããç¬èªã®ã¹ã¿ãã¯ãæã£ãŠããŸãã Goã®ãã«ãã¹ã¬ããã¢ãã«ã®æ§æã«ã¯ãå³å¯ãªçè«ãã€ãŸãçžäºäœçšããé次Hoareããã»ã¹ïŒ CSP ïŒã®çè«ããããããã¯äžŠåã·ã¹ãã ã®æ©èœãæ£åŒã«èšè¿°ããããã«äœ¿çšãããããšã«æ³šæããŠãã ããã
Goã¯ãèšå€§ãªæ°ïŒæ°äžããæ°åäžïŒã®go-routineãäœæã§ããããšã§ç¥ãããŠããŸãã ããã¯ãæåã«ãã¹ãŠã®go-routineãäœæã«éåžžã«å°ãªããªãœãŒã¹ãå¿ èŠãšãããšããäºå®ã®ããã«å¯èœã§ã-ããªãã¡ããããã¯ãã¹ãŠå°ããªã¹ã¿ãã¯ãµã€ãºïŒ2Kã¹ã¿ãã¯å¯Ÿæšæºã®Linux / x86-32ã¹ããªãŒã ã®å Žåã¯2MïŒã§äœæãããŸããã¹ã¿ãã¯ã¯å¿ èŠã«å¿ããŠåå²ãåœãŠãããŸãã go-routineã®çžäºäœçšã®æ段ã¯ãã£ãã«ã§ãã
ããã«ãããCã³ãŒã«ããã®ã·ã¹ãã ã«ã©ã®ããã«é©åããã®ããšããçåãçããŸãã goã«ãŒãã³ã®å Žåãšåãããã«ãCé¢æ°ã®ããŒãºã«å¯ŸããŠã¹ã¿ãã¯ãå¢å ããŸããïŒ åœŒå¥³ãå€ç·é»è©±ãããããšããã©ã®ããã«ãŽãŒã«ãŒãã³ãèšç»ããŸããïŒ æåã¯ãããã¯ãã¹ãŠæçœã§ã¯ãããŸããã
æåã«ãå€éšåŒã³åºããè¡ããã«ãgo-routineã®äžè¬çãªã¡ã«ããºã ãç解ããŸãããã ãã¹ãŠãã©ã®ããã«æ©èœããããç解ããããã«ãéåžžãæåg ã mãããã³pã§ç€ºãããGoã®å éšãšã³ãã£ãã£ãæ€èšããŸãã ãããããgo-schedulerããã€ã¹ã«é¢ããèšäºã§èª°ãããããã«ç²ŸéããŠããã§ãããããã®ç¿»èš³çãå ¥æå¯èœã§ã ã
gã¯goã«ãŒãã³ã®ãã³ãã«æ§é ã§ãã ã¹ã¿ãã¯ã®çŸåšã®å¢çã®ããŒã¿ãããã°ã©ã ã«ãŠã³ã¿ãŒãããã³ãã®go-routineãå®è¡ãããçŸåšã®ã·ã¹ãã ã¹ã¬ããã®ãã³ãã«ãžã®ãã€ã³ã¿ãŒãªã©ã1ã€ã®go-routineã«åºæã®ãã¹ãŠã®æ å ±ãå«ãŸããŸãïŒ mã§ç€ºãããŸãïŒ ã Goã«ãŒãã³ã¯ãã¹ã±ãžã¥ãŒã©ã«ãã£ãŠå®è¡ãããŸããã¹ã±ãžã¥ãŒã©ã¯ããã®ããã«é©åãªã¿ã€ãã³ã°ã§åŒã³åºãããŸããããšãã°ãå®è¡å¯èœãªGoã«ãŒãã³ãã·ã¹ãã ã³ãŒã«ãŸãã¯I / Oæäœãè¡ãå Žåã§ãã
Goã©ã³ã¿ã€ã ã«ãã£ãŠäœæãããåã·ã¹ãã ã¹ã¬ããã¯ãæ§é äœmã«ãã£ãŠèšè¿°ãããŸãã Mã«ã¯ãã¹ããªãŒã ã®å éšããŒã¿ãå«ãŸããŸãããã®èå¥åããã®äžã§å®è¡ãããŠããçŸåšã®go-routineãç¶æ ã®èª¬æãã£ãŒã«ãïŒã¹ãã³ããããã¯ãæ¶æ» ïŒããã³ãã®ä»ã®Goåºæã®ãã£ãŒã«ãããããŸãã ãããããšãããèå³æ·±ãããŒã¿ããããŸãããããã¯ãã¹ããªãŒã ã«å²ãåœãŠãããã¹ã¿ãã¯ã®å¢çã§ããããå®è¡ã³ã³ããã¹ãããšåŒã°ãããã®ãžã®ãã€ã³ã¿ãŒã§ãã
å®è¡ã³ã³ããã¹ãpãç¹å¥ãªæ§é ã§ãã ã·ã¹ãã ã¹ã¬ããmã¯ãgoã«ãŒãã³ãå®è¡ããããã«ã³ã³ããã¹ããå¿ èŠãšããŸãã èªèº«ã®å éšã§ãpã¯å®è¡ã®æºåãã§ããŠããgo-routineã®ããŒã«ã«ãã¥ãŒãæ ŒçŽããŸãã mãã³ã³ããã¹ãp ãååŸãããšããã®ã³ã³ããã¹ãã«å±ããããŒã«ã«ãã¥ãŒããgo-routineãå®è¡ã§ããŸãã ããŒã«ã«ãã¥ãŒã空ã®å Žåãä»ã®pã®ãã¥ãŒããã®ã¯ãŒã¯ã¹ãã£ãŒãªã³ã°ãçºçããŸãã ãã¹ãŠã®pãå®æçã«ãã§ãã¯ããã°ããŒãã«ãã¥ãŒããããŸãã
éåžžãåæã«å€æ°ã®ã·ã¹ãã ã¹ã¬ãããååšããããšãç解ããããšãéèŠã§ããå€ãã®å Žåãã³ã³ããã¹ã以å€ã®ãã®ããããŸãã ãã ããã³ã³ããã¹ããæã€ã¹ã¬ããã®ã¿ãgo-routineã®å®è¡ã«é¢äžã§ããŸãã ã³ã³ããã¹ãã®æ°ã¯ãGOMAXPROCSç°å¢å€æ°ã«ãã£ãŠèšå®ã§ããŸããããã©ã«ãã§ã¯ãããã»ããµã³ã¢ã®æ°ãšåãã§ãã ã³ã³ããã¹ãã®æ°ã¯åºå®ãããŠãããããgoã«ãŒãã³ã®ã»ããå šäœã¯ãæå®ãããæ°ã®OSã¹ã¬ããã«ãã£ãŠå€éåãããŸãã
ã³ã³ããã¹ããå°å ¥ãããã€ã³ãã¯ãç°ãªãOSã¹ã¬ããéã§è»¢éã§ããããšã§ãããããŒã«ã«ã³ã³ããã¹ããã¥ãŒããã®éåžžã®go-routineã¯éãã«æ°ä»ããªãã§ãããã ããã¯ãã€å¿ èŠã«ãªããŸããïŒ æ¬¡ã«ãäœããã®çš®é¡ã®ããããã³ã°ã¿ã¹ã¯ã®ããã«çŸåšã®ã¹ã¬ããã解æŸããå¿ èŠãããå Žåã ã³ã³ããã¹ããæž¡ãããšãã§ããªããšæ³åããŠã¿ãŸãããã 次ã«ãããããã®go-routineãã·ã¹ãã ã³ãŒã«ãè¡ãå ŽåãããŒã«ã«ãã¥ãŒã«æ®ã£ãŠãããã®ã¯ã¢ã€ãã«æéãæå³ããŸãã ãŸããã·ã¹ãã ã³ãŒã«ã¯ãããã¯ãããå¯èœæ§ããããããgo-routineã¯ç¡æéã«ãããã¯ããããŸãŸã«ãªãå¯èœæ§ããããããã¯èš±å¯ãããŸããã ã³ã³ããã¹ããæž¡ãããšã§ãã®åé¡ã解決ãããã®ãããªå Žåã§ããã¥ãŒããã®go-routineãå®è¡ãç¶ããããšãã§ããŸãã ãã®ãããã·ã¹ãã ã³ãŒã«ãè¡ãåã«ãã³ã³ããã¹ãã¯ä»ã®ç©ºãã·ã¹ãã ã¹ã¬ããmã«è»¢éããããã¥ãŒã¯ãã®æ°ããã¹ã¬ããã§åŠšããããããšãªãåäœãç¶ããŸãã ã·ã¹ãã ã³ãŒã«ã¯å ã®ã¹ã¬ããã§å®è¡ãããŸãããå®è¡ã³ã³ããã¹ãã¯ãããŸããã
ããã§ãåºæ¬ãšã³ãã£ãã£gãmãpã調ã¹ãå°ãã®ã·ã¹ãã ã³ãŒã«ã«è§ŠããŸããã 次ã«ãGoã§ã®å€éšåŒã³åºãã®åé¡ã«ã€ããŠèª¬æããŸãã
å€ç·çºä¿¡æ¹æ³
ã芧ã®ãšãããGoã§ã¯ãå®è¡é¢æ°ã¯Cé¢æ°ã§ã¯ãŸã£ããçãããã®ã§ãã ãããã£ãŠãå€éšåŒã³åºãã¯ãgo-routineã¡ã«ããºã 以å€ã®ç¹å¥ãªæ¹æ³ã§åŠçããå¿ èŠããããŸãã ããããGoã§ã®ã·ã¹ãã ã³ãŒã«ã®åŠçã«ã€ããŠã¯ãã§ã«è©±ãå§ããŠããŸãããã·ã¹ãã ã³ãŒã«ãCé¢æ°å ã«ããå Žåã¯ã©ãã§ããããã ãããç¥ãããšãã§ããªããããGoã®èŠ³ç¹ããã®ä»»æã®Cé¢æ°ãåŠçããŠããã®å éšã®ã·ã¹ãã åŒã³åºããæ£ããæ©èœããããã«ããå¿ èŠããããŸãã ãããã£ãŠãGo Cã³ãŒã«ãšã·ã¹ãã ã³ãŒã«ã®åŠçã«ã¯ãããã€ãã®å ±éç¹ãå¿ èŠã§ãã ãããããã詳现ã«èŠãŠã¿ãŸãããããéäžã§éãã«æ³šæããŸãã
syscallãšä»»æã®CåŒã³åºãã®äž¡æ¹ããå¥åã®ã·ã¹ãã ã¹ã¬ããã§å®è¡ãããŸãã
Cã³ãŒã«ãçºä¿¡ããã®ã«ã©ã®ãããæéããããããäºåã«ç¥ãããšã¯ã§ããŸããã ã·ã¹ãã ã³ãŒã«ãšåãããã«ããããã¯ãããå¯èœæ§ããããä»ã®go-routineã¯ããã«æ©ãŸãããã¹ãã§ã¯ãããŸããã ãããã£ãŠãCåŒã³åºãã¯ãã·ã¹ãã åŒã³åºãã®ããã«ãã³ã³ããã¹ããå¥ã®mã«æž¡ããåŸãåžžã«å¥ã®ã¹ã¬ããã§å®è¡ãããŸãã åŒã³åºãæã«ããŒã«ã«ç©ºãmããªãã£ãå Žåã mã¯ãã®å Žã§äœæãããŸãã éèŠãªæ³šæïŒCé¢æ°ãšã·ã¹ãã ã³ãŒã«ã®äž¡æ¹ã¯ã³ã³ããã¹ããªãã§å®è¡ããããããGOMAXPROCSã®å¶éã«è©²åœããŸãããã€ãŸããGOMAXPROCS = 1ã®å Žåã§ãå¥ã®ã¹ã¬ããã§å®è¡ãããŸãã ãã®ããã«ããŠãgo-routinesã®å®è¡ã誰ã«ãã£ãŠããããã¯ãããªãããšãä¿èšŒãããŸãã
ãŸããäœæãããã·ã¹ãã ã¹ã¬ããã¯ãã·ã¹ãã ã³ãŒã«ãŸãã¯Cé¢æ°ã®å®äºåŸãæ®ããåå©çšã§ããæ°ããmã¯åžžã«ã空ãã¹ã¬ããããªãå Žåã«ã®ã¿äœæãããããšã匷調ããŸãã
äž¡æ¹ãšãã¹ã¿ãã¯ã®ãã¹ã€ããããå¿ èŠã§ã
ãæ³åã®ãšãããgo-routineã¹ã¿ãã¯ãšOSã¹ã¬ããã¹ã¿ãã¯ã¯åããã®ã§ã¯ãããŸããã ããã¯ããŽã«ãŒãã³ãã¹ã¬ããã®æ°åã§ããããšã«å ããŠãåãŽã«ãŒãã³ã®ã¹ã¿ãã¯ãµã€ãºãããã°ã©ã äžã«åçã«å€åãããšããèæ ®äºé ãããã§ã«æããã§ãã
å®éãOSã¹ã¬ããã¹ã¿ãã¯ã«é¢ä¿ãªããgo-routineã¹ã¿ãã¯ã¯ããŒãã«å²ãåœãŠãããã©ã³ã¿ã€ã ã«ãã£ãŠãµããŒããããŸãã æåã¯ããã¹ãŠã®go-routineã¯å°ããª2Kã¹ã¿ãã¯ããå§ãŸããã¹ã¿ãã¯ã¯æ¡å€§ããã³çž®å°ã§ããŸãã ã·ã¹ãã ã¹ã¿ãã¯ã¯ã·ã¹ãã ã¹ã¬ããã®æãäžè¬çãªã¹ã¿ãã¯ã§ãããmã ã·ã¹ãã ã¹ã¿ãã¯ã®å¢çãæ ŒçŽããããã«ãæ§é äœmã«ã¯ç¹å¥ãªgo-routine g0ããããŸããããã¯ãã·ã¹ãã ã¹ã¿ãã¯ã®å¢çããã®ã¹ã¿ãã¯ãšããŠæ ŒçŽããããããç¹å¥ã§ãã ãããã£ãŠãGoã®ã·ã¹ãã ã¹ã¿ãã¯ã§åãå ¥ããããŠããè¡šèšæ³ïŒ m-> g0 stack ã
ã·ã¹ãã ã³ãŒã«ãšCé¢æ°ã¯ã m-> g0ã¹ã¿ãã¯ã§æ©èœããŸãã ããããèµ·åããåã«ãã¹ã¿ãã¯ã¹ã€ããããå¿ èŠãªçç±ã§ãã Cé¢æ°ã®å Žåãããã¯runtime.asmcgocallïŒïŒé¢æ°å ã§å®è¡ãããŸãã æåéãã次ã®ããšãèµ·ãããŸãïŒ
- çŸåšã®SPãŽã«ãŒãã³ã¯specã«ä¿åãããŸãã æ§é äœã®ãã£ãŒã«ãmã
- SP go-routinesïŒ=ãã®ã·ã¹ãã ã¹ã¬ããã®SPã
ã·ã¹ãã ã³ãŒã«ã®å Žåãéãã¯ãæé©åã®ç®çã§ããã¹ãŠãã·ã¹ãã ã¹ã¿ãã¯ã§å®è¡ãããã®ã§ã¯ãªãããããæ瀺çã«èŠå®ãããŠããç¹å®ã®å éšé¢æ°ã®ã¿ã§ãããšããããšã§ãïŒãããŠãåãæ¿ãã¯systemstackïŒïŒé¢æ°å ã§è¡ãããŸãïŒã
ã©ã¡ãã®å ŽåããåŒã³åºãã«ãŒãã³ãçŸåšã®ã¹ã¬ããmã«ãã€ã³ãããå¿ èŠããããŸã
ãã®ãããCé¢æ°ãæ£ããå®è¡ããã«ã¯ãã·ã¹ãã ã§å®è¡ããå¿ èŠããããŸã
ã¹ã¿ãã¯ã ãã ãããã1ã€éèŠãªç¹ããããŸããã³ã³ãããŒã«ãCã³ãŒãã«æž¡ãããåã«ãã¹ããªãŒã ããsyshnyãã«ãªããæ°ããgo-routineã®èšç»ã«äœ¿çšã§ããªãããšãã©ã³ã¿ã€ã ã«éç¥ããå¿ èŠããããŸãã ããã¯runtime.LockOSThreadïŒïŒé¢æ°ã䜿çšããŠè¡ãããŸãã ããã«ãããçŸåšã®goã«ãŒãã³ãçµäºãããŸã§ããŸãã¯çŸåšã®goã«ãŒãã³ãruntime.UnlockOSThreadïŒïŒãåŒã³åºããŸã§ããã®mã«ä»ã®goã«ãŒãã³ãå²ãåœãŠãããªããªããŸãã
ã·ã¹ãã ã³ãŒã«ãŸãã¯Cé¢æ°ããæ»ãéã«å€å°ã®é 延ããããŸã
Cé¢æ°ãŸãã¯ã·ã¹ãã ã³ãŒã«ãå®äºããåŸãgo-routineã¯åžžã«ããã«å®è¡ãç¶ç¶ãããšã¯éããŸããã Cé¢æ°èªäœã®å®è¡åã«ãã³ã³ããã¹ãpãå¥ã®ã¹ã¬ããmã«è»¢éãããããšãæãåºããŠãã ããã ããã§åã³Goã³ãŒãã®å®è¡ã«æ»ããŸããã€ãŸããå®è¡ãç¶è¡ããã«ã¯ãã³ã³ããã¹ããïŒåããŸãã¯ç°ãªãïŒååŸããå¿ èŠããããŸãã
g-routineã¹ã±ãžã¥ãŒã©ã®çŸåšã®å®è£ ã§ã¯ãæåã«äžããã®ãšåãå®è¡ã³ã³ããã¹ãpãååŸããããšããŸãã ãããæåããå ŽåïŒããšãã°ããã®pã誰ã«ã䜿çšãããŠããããã¢ã€ãã«ç¶æ ã«ããå ŽåïŒãäœæ¥ã¯ç¶ç¶ããŸãïŒé 延ã¯æå°éã§ãïŒã
pãååŸããããšãããã«äžå¯èœã§ãä»ã®ãã¹ãŠã®pãããžãŒã§ããå Žåãgoã«ãŒãã³ã¯ãããã¯ãããŸãã ããã®çç±ã¯ãæ¢åã®GOMAXPROCSã®å¶éã§ãïŒåæã«$ GOMAXPROCSã® go- routineãå®è¡ããããšã¯ã§ããŸããïŒã€ãŸããã³ã³ããã¹ããããã ãã§ãïŒã ãã€ãŸã äœããã®çš®é¡ã®ããããã³ã°æäœãè¡ããŸãã CåŒã³åºãããæ»ã£ãåŸãgo-routineã¯èª°ããèªåã®èªç±æå¿ã®æèã«ãéãè²ãããŸã§åŸ ããªããã°ãªããªãããšãããããŸãã å€éšåŒã³åºããé »ç¹ã«çºçããå ŽåãCåŒã³åºãããæ»ããšãã«pã解æŸãããã®ãåŸ ã€ãšããã¹ãŠãå°ç¡ãã«ãªããŸãã
ããã¯ã次ã®ã³ãŒããèšè¿°ãããšç°¡åã«ããããŸãã
package main import ( "fmt" "sync" "runtime" ) func main() { runtime.GOMAXPROCS(5) var wg sync.WaitGroup wg.Add(1) go func() { defer wg.Done() work() }() for i := 0; i < 10; i++ { go spinlock() } wg.Wait() } func spinlock() { for { } } func work() { fmt.Println("I am working!") }
ããã§ã¯ãæå®ãããå¶éGOMAXPROCS = 5ã§ãç¡éã®ãµã€ã¯ã«ã§åäœãã10ã®ã«ãŒãã³ãäœæããã次ã«ç»é¢ã«äœãã衚瀺ããå¥ã®ã«ãŒãã³ãäœæãããŸãã ãããããã¹ãŠäœæãããåŸããã®ãã¡5ã€ãã³ã³ããã¹ããååŸããŠå®è¡ãããŸãã ãã®äŸãäœåºŠãå®è¡ãããšãäœæ¥ãæåã«ã³ã³ããã¹ããååŸããŠè§£æ±ºããããšã«æåããç¶æ³ããã£ããã§ããŸãã ãããã5ã€ã®ãç¡éã®ãgo-routineãå®è¡ãéå§ããããšãå€æããå Žåããããã¯ã³ã³ããã¹ãã«è² ãããworkïŒïŒã¯å®è¡ã§ããŸããã
Cé¢æ°åŒã³åºã
Cã³ãŒã«äžã«çºçããã€ãã³ãã®çµéãããäžåºŠè¿œè·¡ããŸãããã ããã€ãã®Cé¢æ°fïŒïŒãåŒã³åºããŸãã ããã¯ãå³ã«ç€ºã次ã®åŒã³åºãã·ãŒã±ã³ã¹ã«å±éãããŸãã å®ç·ã®ç¢å°ã¯é¢æ°åŒã³åºãã瀺ããç¹ç·ã¯å¶åŸ¡ã«æ»ãããšã瀺ããŸãã
åã¹ãããã§äœãèµ·ãããèŠãŠã¿ãŸãããïŒ
ã¹ããã1. Goã«ãŒãã³ãçŸåšã®mã«ä¿è·ããïŒlockOSThreadïŒïŒãåŒã³åºãïŒ
æé 2.ã·ã¹ãã ã¹ã¬ããã®ããŒã«ããmãéžæãïŒç©ºãmããªãå Žå-æ°ããã¹ã¬ãããäœæããïŒãéžæããmã«ã³ã³ããã¹ãã転éãã
ã¹ããã3. Go-routineã¹ã¿ãã¯ãm-> g0ã«åãæ¿ããŠããªãã¬ãŒãã£ã³ã°ã·ã¹ãã ã®ã¹ã¬ããã¹ã¿ãã¯
ã¹ããã4. Cé¢æ°fã®åŒã³åºããæºåããé¢æ°èªäœãçŽæ¥åŒã³åºããŸãã æºåã¯ãç¹å®ã®ã¢ãŒããã¯ãã£ã«å¯Ÿå¿ããåŒã³åºãèŠçŽãžã®çž®å°ãšããŠç解ãããŸãïŒããšãã°ã x86_64ã§ã¯ ãé¢æ°ã®åŒæ°ã¯å¯Ÿå¿ããã¬ãžã¹ã¿ã«æ ŒçŽãããŸãïŒã Cé¢æ°ã«ããå€ã®æ»ããæ £äŸã«ããçºçãããããå¿ èŠã«å¿ããŠãã£ã¹ããè¡ãããŸãïŒx86_64ã§ã¯ãã¬ãžã¹ã¿ããã®æ»ãå€ãã¹ã¿ãã¯ã«ç§»åãããŸãïŒ
ã¹ããã5. OSã¹ã¬ããã¹ã¿ãã¯ããçŸåšã®go-routineã®ã¹ã¿ãã¯ãžã®éåãæ¿ãïŒ m-> curg stackïŒ
ã¹ããã6. ExitsyscallïŒïŒ-å éšã§ã¯ã$ GOMAXPROCSã®å¶éã«éåããããšãªãGoã³ãŒããå®è¡ã§ããããã«ãªããŸã§ãé¢æ°ããããã¯ãããŸã
ã¹ããã7.å®è¡ãå¯èœã«ãªã次第-mããgo-routineã®åºå®ã解é€ããŸãïŒunlockOSThreadïŒïŒïŒ
Goã®äœæè ã¯ãã³ãŒã«ããã¯ãäœæããæ©èœãæäŸããããšã«æ³šæããŠãã ããã ã³ãŒã«ããã¯ã¯æ¬¡ã®ããã«çºçããŸããGoã³ãŒããããCé¢æ°ã®åŒã³åºããè¡ãããåŒæ°ãšããŠGoé¢æ°ãžã®ãã€ã³ã¿ãŒãæž¡ãããŸãã ããã»ã¹å ã®ãã®Cé¢æ°ã¯ãæž¡ããããã€ã³ã¿ãŒã«åŸã£ãŠGoé¢æ°ãåŒã³åºããŸãã
å°ãªããšããåã®éšåã§æ€èšããã±ãŒã¹ã¯ãpã®åŸ æ©ã®é 延ãã³ãŒã«ããã¯ã®æå¹æ§ã«å€§ãã圱é¿ããããšã瀺åããŠããŸãã ããããªããããªã®ãã詳ããèŠãŠã¿ãŸãããã Cã³ãŒã«ã§äœãèµ·ãã£ãŠããããææ¡ããŸããããCããå éšGoã³ãŒããå®è¡ããããã«ã次ã®ã¢ã¯ã·ã§ã³ãå®è¡ãããŸãã
- æ°ããgo-routineãäœæãããŸã
- ãã®åŸãã¹ã¿ãã¯ã¯ã¹ã€ããããã¯ãããŸãïŒã·ã¹ãã ããæ°ããgo-routineã®ã¹ã¿ãã¯ã«ïŒ
- æ°ããgo-toã«ãŒãã³ã«ã¯pãå¿ èŠã§ãã ãããã£ãŠãå€éšåŒã³åºãããæ»ããšããšåãããã«ããããã¯ãããäžéšã®pã解æŸããããŸã§åŸ æ©ããŸãã
ãããã£ãŠãã³ãŒã«ããã¯ã®å ŽåãCã³ãŒã«ããã®åŸ©åž°ã§æ¢ã«èæ ®ãããŠããé 延ïŒfree pã®æåŸ ã«ããïŒã«å ããŠãåãæ§è³ªã®ãã1ã€ã®é 延ããããŸãã åŸ æ©æépããªãŒããŒãããã«2åã®è²¢ç®ãããããšãããããŸãã
ãããããŸããããã ãªãŒããŒããã
ãããã£ãŠãgo-routinesããã®å€éšåŒã³åºãããçããã³ã¹ãã®æ§è³ªãããäžåºŠç€ºããŠã¿ãŸãããã
ç¶æ³1. Goã«ãŒãã³ã¯ãCé¢æ°ããæ»ã£ãåŸã«pã解æŸãããããšãæåŸ ããŠããŸãã
ãã®ç¶æ³ã§ã¯ãå¿é ããããšã¯äœããªãããã«æãããŸãã ããããå€ãã®go-routineãããããããããã®CåŒã³åºããé »ç¹ã«çºçããããšãæ³åããŠã¿ãŠãã ããïŒããšãã°ããæ°ã«å ¥ãã®ã©ã€ãã©ãªã®ã©ãããŒãäœæããGoã®ãã¹ãŠã®èŠç¯ã«åŸã£ãŠãå€ãã®go-routineã䜿çšããŠã¿ãŸãããïŒã è€æ°ã®Cã³ãŒã«ã䜿çšãããšããããã®é 延ã¯ããŸãå¯èœæ§ãé«ããªãã次ã«é·ããªããŸãã
ç¶æ³2.次ã®å€éšåŒã³åºãã§ãæ®ãã®go-routineãå®è¡ããããã®ååãªç©ºãã¹ã¬ããããããŸããã§ããã
ãã®å Žåãæ°ããã¹ã¬ããã匷å¶çã«äœæãããå®è¡ã³ã³ããã¹ããã¹ã¬ããã«è»¢éãããŸãã ãã®ãããæãåçŽãªCé¢æ°ã§ãããOSã¹ããªãŒã ãäœæãããªãŒããŒããããšåçã®å€§å¹ ãªé 延ã§å®è¡ãããŸãã ãã®çš®ã®é 延ã¯ãããã°ã©ã ã®åäœäžã«äºæž¬ããããšã¯ã§ããŸãããããã¯ããããŒãå¿ èŠã«å¿ããŠäœæãããããã§ãã
ãããã®ã³ã¹ããè©äŸ¡ããããã«ã2ã€ã®å¯èœãªç¶æ³ã§gã«ãŒãã³ãã空ã®Cé¢æ°ãåŒã³åºãã®ã«ããã£ãæéã枬å®ã§ããŸãã
1ïŒæ°ããã¹ã¬ãããäœæãããç¶æ³ã
2ïŒæ¢åã®ã¹ããªãŒã ãåå©çšãããå Žåã
ãããç§ãã¡ãããããšã§ãã 以äžã¯ãããŒã¿ãååŸããç°¡åãªããã°ã©ã ã§ãã
package main // Run program as ./program pb=<int> // where pb means P_blocked - number of Ps to be in a spinlock. // Program prints to console time (in nanoseconds) elapsed by one C call that is done in goroutine import "fmt" import "time" import "flag" import "sync" // int empty_c_foo() {} // import "C" func spin_lock() { for { } } func main() { var wg sync.WaitGroup wg.Add(1) pb_ptr := flag.Int("pb", 3, "number of Ps that will be in spinlock") flag.Parse() P_blocked := *pb_ptr for i := 0; i < P_blocked; i++ { // «» go spin_lock() } go func() { // C.empty_c_foo() // 2 defer wg.Done() time1 := time.Now() C.empty_c_foo() time2 := time.Now() fmt.Println(int64(time2.Sub(time1))) }() wg.Wait() }
ãã©ã°ã©ã1ã§ã¯ãæåã«åŒã³åºããã1ã€ã®ç©ºã®Cé¢æ°ã®æéã枬å®ããã ãã§ååã§ã-ãããæåã®å€éšåŒã³åºãã«ãªãããããããçºçããæç¹ã§ãããŒã«ã«ç©ºãmããªãããšãä¿èšŒãããŸããã€ãŸããå¿ èŠãªã¹ããªãŒã ãäœæãããŸãã ã±ãŒã¹2ã§ã¯ãããã°ã©ã ã¯äŒŒãŠããŸãããCã³ãŒã«ã®ç¹°ãè¿ãã«å¯ŸããŠãã§ã«æž¬å®ãè¡ãããŠããŸããæåã®ã³ãŒã«ã§mããã§ã«äœæããããããã³ã¹ããå€§å¹ ã«åæžããããšäºæ³ãããŸãã
ãããŒãããããã©ã³ã¿ã€ã ãã·ãã¥ã¬ãŒãããããã«ãäžå®ã®æ°ã®go-routineãäœæãããç¡éã®ãµã€ã¯ã«ã§å æãããŸããããã®æ°ã¯P_spinlocked = 5ã10ã15ã...ã35ã§ç€ºããããã®ãããªå€ããšã«100,000ã®ããã°ã©ã ãéå§ããã枬å®ãè¡ãããŸããã ããã°ã©ã ã¯ãIntel®Xeon®CPU E5-2697 v2 @ 2.70GHzã§å®è¡ãããŸããã 48ã³ã¢ããã©ã¡ãŒã¿ãŒGOMAXPROCS = 40ã®ãã·ã³ã§ã¯ããã·ã³ã¯æä»çã«äœ¿çšãããŠããŸããã
æ°ããã¹ã¬ãããäœæããããšãã®CåŒã³åºãã®å®éšçµæ
çªå·P_spinlocked = | 5 | 10 | 15 | 20 | 25 | 30 | 35 |
---|---|---|---|---|---|---|---|
ïŒ æåºé>å¹³å+ 3çªç®ã®åå·® | 0.28ïŒ | 0.36ïŒ | 0.31ïŒ | 0.31ïŒ | 0.30ïŒ | 0.27ïŒ | 0.28ïŒ |
å¹³å | 2537 | 2438 | 2518 | 2534 | 2626 | 2686 | 2719 |
æšæºåå·® | 201 | 470 | 200 | 224 | 346 | 369 | 393 |
äžå€®å€ | 2512 | 2523 | 2493 | 2500 | 2540 | 2590 | 2613 |
æ倧 | 58182 | 65798 | 59543 | 58243 | 55700 | 66620 | 59600 |
æäœ | 972 | 870 | 1011 | 909 | 1005 | 975 | 937 |
ã¹ããªãŒã ãæ¢ã«äœæãããŠããå Žåã®CåŒã³åºãã®å®éšçµæ
çªå·P_spinlocked = | 5 | 10 | 15 | 20 | 25 | 30 | 35 |
---|---|---|---|---|---|---|---|
ïŒ æåºé>å¹³å+ 3çªç®ã®åå·® | 0.06ïŒ | 0.09ïŒ | 0.10ïŒ | 0.12ïŒ | 0.13ïŒ | 0.15ïŒ | 0.16ïŒ |
å¹³å | 1123 | 1126 | 1137 | 1172 | 1250 | 1283 | 1313 |
æšæºåå·® | 183 | 212 | 226 | 300 | 433 | 456 | 492 |
äžå€®å€ | 1086 | 1076 | 1080 | 1086 | 1099 | 1117 | 1123 |
æ倧 | 68461 | 73383 | 53756 | 49751 | 50581 | 47844 | 86258 |
æäœ | 391 | 354 | 364 | 348 | 313 | 340 | 351 |
ãŸããã±ãŒã¹1ãšã±ãŒã¹2ã®Cã³ãŒã«æéã®ååžãæ¯èŒããŸãïŒã©ã³ã¿ã€ã P_spinlocked = 35ã®è² è·ãçããå ŽåïŒã ããã«æåŸ ãããçµæã衚瀺ãããŸã-æ°ããã¹ããªãŒã ãäœæããå Žåãæéãé·ããªããŸãã å¹³åå€ã¯çŽ2åç°ãªãã1ã±ãŒã¹ãš2ã±ãŒã¹ã§ããããçŽ2600 nsãšã1200 nsã§ãã
以äžã®åã±ãŒã¹ã®å³ã¯ãäœè² è·ïŒP_spinlocked = 5ïŒããã³é«è² è·ïŒP_spinlocked = 35ïŒïŒæåºéãé€ãïŒã®æéã®ååžãåå¥ã«ç€ºããŠããŸãã
ã©ã³ã¿ã€ã ã®è² è·ãåŸã ã«å¢å ããããšã§ãã©ã³ã¿ã€ã ç°å¢ã®äœæ¥ã«é¢é£ããã³ã¹ããã©ã®ããã«å¢å ãããã確èªã§ããŸãããè² è·ãå¢å ãããšãå¹³åå€ã®ã¹ã ãŒãºãªã·ããã芳å¯ãããŸãã ããã¯ã以äžã®ãã¹ãã°ã©ã ãããæ確ã«èŠãããšãã§ããŸããããŒããããã©ã³ã¿ã€ã ïŒP_spinlocked = 35ïŒã®å Žåããã¹ãã°ã©ã ã¯ã¢ã³ããŒãïŒP_spinlocked = 5ïŒãšæ¯èŒããŠé«ãå€ã«åãã£ãŠã䟵é£ãããã©ã³ã¿ã€ã ã®è€éããäžå®ã§ãªãããšã瀺ããŸãgo-routineã®æ°ã
ãŸããäž¡æ¹ã®ã±ãŒã¹ã§ãããªãã®æåºéã®å²åã®å²åïŒã50,000 ns以äžïŒãããããšã«æ³šæããå¿ èŠããããŸãã ïŒããã¯å¥åŠã§ãã2çªç®ã®ã±ãŒã¹ã§ã¯ã¹ããªãŒã ããã§ã«äœæãããŠãããå€§å¹ ãªé 延ã¯ãªãã¯ãã§ãããããã§ãæåã®ã±ãŒã¹ãšåãé åºã®æŸåºããããŸããæããã«ãçç±ã¯ã¹ã¬ããã®äœæã«é¢ä¿ããªããªãã¬ãŒãã£ã³ã°ã·ã¹ãã ã®æ©èœã«ãããŸãïŒ
äžã®ãã¹ãã°ã©ã ïŒy軞ã«æ²¿ã£ã察æ°ç®çïŒã¯ãå®è¡æéP_spinlocked = 10ã®è² è·ãçããäž¡æ¹ã®å Žåã®ãå€ãå€ãå«ããã¹ãŠã®ãã€ã³ãã瀺ããŠããŸããããã§ã¯ãååŸãããã¹ãŠã®å€ã®å€ãå€ã®ã·ã§ã¢ãæšå®ã§ããŸãã
å®éšä»¥å€ã§ã¯ãã¬ããŒãžã³ã¬ã¯ã¿ãŒã®è²¢ç®ã¯æ®ããŸãã ç§ãã¡ã®å®éšã§ã¯ã匷å¶çã«ãªãã«ããŸããã å®éã®æ¡ä»¶ã§ã¯ãããã°ã©ã ã®å®è¡ãå®æçã«å®å šã«åæ¢ãããé決å®æ§ã®äžéšã«å¯äžããŸãïŒããããäžçåæ¢æ®µéïŒã Goéçºè ã¯ãäœæ¥ãæ¹åããããã°ã©ã ã®é¢é£ããäžæåæ¢ãæå°éã«æããããšã«å€§ããªæ³šæãæã£ãŠããŸãã Go 1.5ã§ã¯ãã³ã¬ã¯ã¿ãŒã®äœæ¥ãå€§å¹ ã«æé©åãããŠããŸã -å®å šåæ¢ã®æéã10ããªç§ãè¶ ããªãããšãä¿èšŒãããŠããŸããããã¯éåžžã«è¯ãããšã§ãã
ãããã«
å€ç·é話ã¯éåžžã«è²»çšãããããŸãã ããã«ãã©ã³ã¿ã€ã èªäœã¯ãã¬ããŒãžã³ã¬ã¯ã¿ãŒãç¡å¹ã«ãªã£ãŠããå Žåã§ããå€éšåŒã³åºãã®å®è¡ã§äºæããªãå€§å¹ ãªé 延ãåŒãèµ·ããå¯èœæ§ããããŸããã¬ããŒãžã³ã¬ã¯ã¿ãŒãç¡å¹ã«ãªã£ãŠããå ŽåããããŒãããäœæããgo-routineã¯ã¡ã¢ãªã§åäœããªããããã¹ã¿ãã¯ã®è¿œå ãåŒãèµ·ãããŸããã ãããŒãããŽã«ãŒãã³ã¯ãã¹ã±ãžã¥ãŒã©ãŒã®åŒã³åºããåŒãèµ·ããå¯èœæ§ã®ããé«äŸ¡ãªæäœãè¡ããŸãã-ã€ãŸãããããã¯ãŸã åã¹ã±ãžã¥ãŒã«ãããŠããŸããã å®éã«ã¯ãå®éã«ããŒããããgo-routineã䜿çšãããšãå€ã®åºãããå€§å¹ ã«å¢å ããŸãã
ã¹ã¬ããã®äœæã«ããé 延ã¯ãããšãã°ãããã°ã©ã ã®éå§æã«ã¹ã¬ããã®äžéšãäœæããããšã§åé¿ã§ããŸãã ãã ããç¡æã®ã³ã³ããã¹ãã®åŸ æ©æéã¯äºæž¬äžèœãªãŸãŸã§ãããé »ç¹ã«å€éšåŒã³åºããè¡ããšå¢å ããã ããªã®ã§ãæ²ããäºå®ãèªããå¿ èŠããããŸã-gogoã«ãŒãã³ããã®cgoã®ç©æ¥µçãªäœ¿çšã¯ãããã°ã©ã ã®å šäœçãªæå¹æ§ã«æªåœ±é¿ãäžããæã ããã ãã«é Œã䟡å€ããããŸã ãã¡ããã倧ããªé 延ã®å¯èœæ§ã¯éåžžã«å°ããã§ããããœãããªã¢ã«ã¿ã€ã ã·ã¹ãã ã§ãã£ãŠããGoã§ã®å€éšåŒã³åºãã®äœ¿çšãåé¡ã«ãªãå¯èœæ§ããããŸãã