éçºè ããã³ã·ã¹ãã 管çè åãã䞊ååŠçæè¡ãçšãããã«ãã³ã¢CPUã®å©çšãæå€§éã«é«ããå æ¬çãªã¬ã€ãã
ããã©ãŒãã³ã¹ã®è§£æŸïŒäžŠååŠçã«ãããã«ãã³ã¢CPUã®å©çš
仿¥ã®ã³ã³ãã¥ãŒãã£ã³ã°ç°å¢ã§ã¯ããã«ãã³ã¢CPUã¯è³ãæã«ååšããŸããã¹ããŒããã©ã³ãããµãŒããŒãŸã§ããããã®ããã»ããµã¯å€§ããªããã©ãŒãã³ã¹åäžã®å¯èœæ§ãæäŸããŸãããããããã®å¯èœæ§ãå®çŸããã«ã¯ã䞊ååŠçãšè€æ°ã®ã³ã¢ãåæã«å¹æçã«å©çšããæ¹æ³ããã£ãããšçè§£ããå¿ èŠããããŸãããã®ã¬ã€ãã¯ã䞊ååŠçã«ãããã«ãã³ã¢CPUã®å©çšã«é¢ããå æ¬çãªæŠèŠãæäŸããããšãç®çãšããŠãããéçºè ããã³ã·ã¹ãã 管çè åãã®éèŠãªæŠå¿µããã¯ããã¯ãããã³å®è·µçãªäŸãç¶²çŸ ããŠããŸãã
ãã«ãã³ã¢CPUã®çè§£
ãã«ãã³ã¢CPUã¯ãåºæ¬çã«è€æ°ã®ç¬ç«ããåŠçãŠãããïŒã³ã¢ïŒãåäžã®ç©çãããã«çµ±åããããã®ã§ããåã³ã¢ã¯ç¬ç«ããŠåœä»€ãå®è¡ã§ãããããCPUã¯è€æ°ã®ã¿ã¹ã¯ãåæã«å®è¡ã§ããŸããããã¯ãäžåºŠã«1ã€ã®åœä»€ããå®è¡ã§ããªãã·ã³ã°ã«ã³ã¢ããã»ããµããã®å€§ããªè±åŽã§ããCPUå ã®ã³ã¢ã®æ°ã¯ã䞊åã¯ãŒã¯ããŒããåŠçããèœåã®éèŠãªèŠçŽ ã§ããäžè¬çãªæ§æã«ã¯ããã¥ã¢ã«ã³ã¢ãã¯ã¢ããã³ã¢ããããµã³ã¢ïŒ6ã³ã¢ïŒããªã¯ã¿ã³ã¢ïŒ8ã³ã¢ïŒãããã³ãµãŒããŒããã€ããã©ãŒãã³ã¹ã³ã³ãã¥ãŒãã£ã³ã°ç°å¢ã§ã®ããã«é«ãã³ã¢æ°ããããŸãã
ãã«ãã³ã¢CPUã®å©ç¹
- ã¹ã«ãŒãããã®åäžïŒãã«ãã³ã¢CPUã¯ããå€ãã®ã¿ã¹ã¯ãåæã«åŠçã§ãããããå šäœçãªã¹ã«ãŒããããåäžããŸãã
- å¿çæ§ã®åäžïŒã¿ã¹ã¯ãè€æ°ã®ã³ã¢ã«åæ£ããããšã§ãã¢ããªã±ãŒã·ã§ã³ã¯é«è² è·æã§ãå¿çæ§ãç¶æã§ããŸãã
- ããã©ãŒãã³ã¹ã®åäžïŒäžŠååŠçã¯ãèšç®éçŽçãªã¿ã¹ã¯ã®å®è¡æéãå€§å¹ ã«ççž®ã§ããŸãã
- ãšãã«ã®ãŒå¹çïŒå Žåã«ãã£ãŠã¯ãè€æ°ã®ã³ã¢ã§è€æ°ã®ã¿ã¹ã¯ãåæã«å®è¡ããæ¹ããåäžã®ã³ã¢ã§é çªã«å®è¡ããããããšãã«ã®ãŒå¹çãé«ããªãããšããããŸãã
䞊ååŠçã®æŠå¿µ
䞊ååŠçã¯ãè€æ°ã®åœä»€ãåæã«å®è¡ãããã³ã³ãã¥ãŒãã£ã³ã°ãã©ãã€ã ã§ããããã¯ãåœä»€ã次ã ãšå®è¡ããã鿬¡åŠçãšã¯å¯Ÿç §çã§ãã䞊ååŠçã«ã¯ããã€ãã®çš®é¡ããããããããã«ç¬èªã®ç¹åŸŽãšã¢ããªã±ãŒã·ã§ã³ããããŸãã
äžŠåæ§ã®çš®é¡
- ããŒã¿äžŠåæ§ïŒåãæäœãè€æ°ã®ããŒã¿èŠçŽ ã«å¯ŸããŠåæã«å®è¡ãããŸããããã¯ãç»ååŠçãç§åŠã·ãã¥ã¬ãŒã·ã§ã³ãããŒã¿åæãªã©ã®ã¿ã¹ã¯ã«é©ããŠããŸããããšãã°ãç»åã®ãã¹ãŠã®ãã¯ã»ã«ã«åããã£ã«ã¿ãŒãé©çšããããšã¯ã䞊è¡ããŠå®è¡ã§ããŸãã
- ã¿ã¹ã¯äžŠåæ§ïŒç°ãªãã¿ã¹ã¯ãåæã«å®è¡ãããŸããããã¯ãã¯ãŒã¯ããŒããç¬ç«ããã¿ã¹ã¯ã«åå²ã§ããã¢ããªã±ãŒã·ã§ã³ã«é©ããŠããŸããããšãã°ãWebãµãŒããŒã¯è€æ°ã®ã¯ã©ã€ã¢ã³ããªã¯ãšã¹ããåæã«åŠçã§ããŸãã
- åœä»€ã¬ãã«äžŠåæ§ïŒILPïŒïŒããã¯ãCPUèªäœã«ãã£ãп޻çšãããäžŠåæ§ã®åœ¢åŒã§ããææ°ã®CPUã¯ããã€ãã©ã€ã³åŠçãã¢ãŠããªããªãŒããŒå®è¡ãªã©ã®ææ³ã䜿çšããŠãåäžã®ã³ã¢å ã§è€æ°ã®åœä»€ãåæã«å®è¡ããŸãã
äžŠè¡æ§ãšäžŠåæ§
äžŠè¡æ§ãšäžŠåæ§ãåºå¥ããããšãéèŠã§ããäžŠè¡æ§ãšã¯ãã·ã¹ãã ãè€æ°ã®ã¿ã¹ã¯ãåæã«åŠçããèœåã®ããšã§ããäžŠåæ§ãšã¯ãè€æ°ã®ã¿ã¹ã¯ãå®éã«åæã«å®è¡ããããšã§ããã·ã³ã°ã«ã³ã¢CPUã¯ãã¿ã€ã ã·ã§ã¢ãªã³ã°ãªã©ã®ææ³ãéããŠäžŠè¡æ§ãå®çŸã§ããŸãããçã®äžŠåæ§ãå®çŸããããšã¯ã§ããŸããããã«ãã³ã¢CPUã¯ãè€æ°ã®ã¿ã¹ã¯ãç°ãªãã³ã¢ã§åæã«å®è¡ã§ããããã«ããããšã§ãçã®äžŠåæ§ãå®çŸããŸãã
ã¢ã ããŒã«ã®æ³åãšã°ã¹ã¿ããœã³ã®æ³å
ã¢ã ããŒã«ã®æ³åãšã°ã¹ã¿ããœã³ã®æ³åã¯ã䞊ååã«ããããã©ãŒãã³ã¹åäžã®éçãæ¯é ãã2ã€ã®åºæ¬çãªååã§ãããããã®æ³åãçè§£ããããšã¯ãå¹ççãªäžŠåã¢ã«ãŽãªãºã ãèšèšããããã«äžå¯æ¬ ã§ãã
ã¢ã ããŒã«ã®æ³å
ã¢ã ããŒã«ã®æ³åã¯ãããã°ã©ã ã䞊ååããããšã«ãã£ãŠéæã§ããæå€§ã¹ããŒãã¢ããã¯ã鿬¡çã«å®è¡ããå¿ èŠãããããã°ã©ã ã®å²åã«ãã£ãŠå¶éããããšè¿°ã¹ãŠããŸããã¢ã ããŒã«ã®æ³åã®åŒã¯æ¬¡ã®ãšããã§ãã
Speedup = 1 / (S + (P / N))
ããã§ïŒ
Sã¯ãã·ãªã¢ã«ãªããã°ã©ã ã®å²åã§ãïŒäžŠååã§ããŸããïŒãPã¯ã䞊ååã§ããããã°ã©ã ã®å²åã§ãïŒP = 1 - SïŒãNã¯ãããã»ããµïŒã³ã¢ïŒã®æ°ã§ãã
ã¢ã ããŒã«ã®æ³åã¯ã䞊ååã«ãã£ãŠå€§å¹ ãªã¹ããŒãã¢ãããéæããããã«ãããã°ã©ã ã®ã·ãªã¢ã«éšåãæå°éã«æããããšã®éèŠæ§ã匷調ããŠããŸããããšãã°ãããã°ã©ã ã®10ïŒ ãã·ãªã¢ã«ã§ããå Žåãããã»ããµã®æ°ã«é¢ä¿ãªããéæå¯èœãªæå€§ã¹ããŒãã¢ããã¯10åã§ãã
ã°ã¹ã¿ããœã³ã®æ³å
ã°ã¹ã¿ããœã³ã®æ³åã¯ã䞊ååã«é¢ããç°ãªãèŠç¹ãæäŸããŸããããã¯ã䞊è¡ããŠå®è¡ã§ããäœæ¥éã¯ãããã»ããµã®æ°ãšãšãã«å¢å ãããšè¿°ã¹ãŠããŸããã°ã¹ã¿ããœã³ã®æ³åã®åŒã¯æ¬¡ã®ãšããã§ãã
Speedup = S + P * N
ããã§ïŒ
Sã¯ãã·ãªã¢ã«ãªããã°ã©ã ã®å²åã§ããPã¯ã䞊ååã§ããããã°ã©ã ã®å²åã§ãïŒP = 1 - SïŒãNã¯ãããã»ããµïŒã³ã¢ïŒã®æ°ã§ãã
ã°ã¹ã¿ããœã³ã®æ³åã¯ãåé¡ãµã€ãºã倧ãããªãã«ã€ããŠã䞊ååã§ããããã°ã©ã ã®å²åãå¢å ããããå€ãã®ããã»ããµã§ããåªããã¹ããŒãã¢ããã«ã€ãªããããšã瀺åããŠããŸããããã¯ãå€§èŠæš¡ãªç§åŠã·ãã¥ã¬ãŒã·ã§ã³ããã³ããŒã¿åæã¿ã¹ã¯ã«ç¹ã«é¢é£ããŠããŸãã
éèŠãªãã€ã³ãïŒã¢ã ããŒã«ã®æ³åã¯åºå®ãããåé¡ãµã€ãºã«çŠç¹ãåœãŠãŠããŸãããã°ã¹ã¿ããœã³ã®æ³åã¯ããã»ããµã®æ°ã§åé¡ãµã€ãºãã¹ã±ãŒãªã³ã°ããããšã«çŠç¹ãåœãŠãŠããŸãã
ãã«ãã³ã¢CPUãå©çšããããã®ãã¯ããã¯
ãã«ãã³ã¢CPUã广çã«å©çšããããã®ãã¯ããã¯ãããã€ããããŸãããããã®ãã¯ããã¯ã«ã¯ãã¯ãŒã¯ããŒãã䞊è¡ããŠå®è¡ã§ããå°ããªã¿ã¹ã¯ã«åå²ããããšãå«ãŸããŸãã
ã¹ã¬ããã£ã³ã°
ã¹ã¬ããã£ã³ã°ã¯ãåäžã®ããã»ã¹å ã§è€æ°ã®å®è¡ã¹ã¬ãããäœæããããã®ãã¯ããã¯ã§ããåã¹ã¬ããã¯ç¬ç«ããŠå®è¡ã§ãããããããã»ã¹ã¯è€æ°ã®ã¿ã¹ã¯ãåæã«å®è¡ã§ããŸããã¹ã¬ããã¯åãã¡ã¢ãªãŒç©ºéãå ±æãããããç°¡åã«éä¿¡ããŠããŒã¿ãå ±æã§ããŸãããã ãããã®å ±æã¡ã¢ãªãŒç©ºéã¯ãç«¶åç¶æ ããã®ä»ã®åæã®åé¡ã®ãªã¹ã¯ãå°å ¥ããæ³šææ·±ãããã°ã©ãã³ã°ãå¿ èŠã§ãã
ã¹ã¬ããã£ã³ã°ã®å©ç¹
- ãªãœãŒã¹ã®å ±æïŒã¹ã¬ããã¯åãã¡ã¢ãªãŒç©ºéãå ±æãããããããŒã¿è»¢éã®ãªãŒããŒããããåæžãããŸãã
- 軜éïŒã¹ã¬ããã¯éåžžãããã»ã¹ããã軜éã§ãããããäœæãšåãæ¿ããé«éã«ãªããŸãã
- å¿çæ§ã®åäžïŒã¹ã¬ããã䜿çšããŠãããã¯ã°ã©ãŠã³ãã¿ã¹ã¯ãå®è¡ããªãããŠãŒã¶ãŒã€ã³ã¿ãŒãã§ã€ã¹ã®å¿çæ§ãç¶æã§ããŸãã
ã¹ã¬ããã£ã³ã°ã®æ¬ ç¹
- åæã®åé¡ïŒåãã¡ã¢ãªãŒç©ºéãå ±æããã¹ã¬ããã¯ãç«¶åç¶æ ããããããã¯ã«ã€ãªããå¯èœæ§ããããŸãã
- ãããã°ã®è€éãïŒãã«ãã¹ã¬ããã¢ããªã±ãŒã·ã§ã³ã®ãããã°ã¯ãã·ã³ã°ã«ã¹ã¬ããã¢ããªã±ãŒã·ã§ã³ã®ãããã°ãããé£ããå ŽåããããŸãã
- ã°ããŒãã«ã€ã³ã¿ãŒããªã¿ãŒããã¯ïŒGILïŒïŒPythonãªã©ã®äžéšã®èšèªã§ã¯ãã°ããŒãã«ã€ã³ã¿ãŒããªã¿ãŒããã¯ïŒGILïŒã¯ã¹ã¬ããã®çã®äžŠåæ§ãå¶éããŸããããã¯ãäžåºŠã«1ã€ã®ã¹ã¬ããã®ã¿ãPythonã€ã³ã¿ãŒããªã¿ãŒã®å¶åŸ¡ãä¿æã§ããããã§ãã
ã¹ã¬ããã£ã³ã°ã©ã€ãã©ãª
ã»ãšãã©ã®ããã°ã©ãã³ã°èšèªã«ã¯ãã¹ã¬ãããäœæããã³ç®¡çããããã®ã©ã€ãã©ãªãçšæãããŠããŸããäŸãšããŠã¯ã次ã®ãã®ããããŸãã
- POSIXã¹ã¬ããïŒpthreadsïŒïŒUnixã©ã€ã¯ã·ã¹ãã ã®æšæºã¹ã¬ããã£ã³ã°APIã
- Windowsã¹ã¬ããïŒWindowsã®ãã€ãã£ãã¹ã¬ããã£ã³ã°APIã
- Javaã¹ã¬ããïŒJavaã«çµã¿èŸŒãŸããŠããã¹ã¬ããã£ã³ã°ã®ãµããŒãã
- .NETã¹ã¬ããïŒ.NET Frameworkã®ã¹ã¬ããã£ã³ã°ã®ãµããŒãã
- Python threadingã¢ãžã¥ãŒã«ïŒPythonã®é«ã¬ãã«ã¹ã¬ããã£ã³ã°ã€ã³ã¿ãŒãã§ã€ã¹ïŒCPUããŠã³ãã¿ã¹ã¯ã®å Žåã¯GILã®å¶éãåããŸãïŒã
ãã«ãããã»ãã·ã³ã°
ãã«ãããã»ãã·ã³ã°ã«ã¯ããããããç¬èªã®ã¡ã¢ãªãŒç©ºéãæã€è€æ°ã®ããã»ã¹ãäœæããããšãå«ãŸããŸããããã«ãããããã»ã¹ã¯GILã®å¶éãå ±æã¡ã¢ãªãŒã®ç«¶åã®ãªã¹ã¯ãªãã«ãçã«äžŠè¡ããŠå®è¡ã§ããŸãããã ããããã»ã¹ã¯ã¹ã¬ãããããéããããã»ã¹éã®éä¿¡ã¯ããè€éã«ãªããŸãã
ãã«ãããã»ãã·ã³ã°ã®å©ç¹
- çã®äžŠåæ§ïŒããã»ã¹ã¯ãGILã䜿çšããèšèªã§ããçã«äžŠè¡ããŠå®è¡ã§ããŸãã
- åé¢ïŒããã»ã¹ã¯ç¬èªã®ã¡ã¢ãªãŒç©ºéãæã€ãããç«¶åãã¯ã©ãã·ã¥ã®ãªã¹ã¯ã軜æžãããŸãã
- ã¹ã±ãŒã©ããªãã£ïŒãã«ãããã»ãã·ã³ã°ã¯ã倿°ã®ã³ã¢ã«é©åã«ã¹ã±ãŒãªã³ã°ã§ããŸãã
ãã«ãããã»ãã·ã³ã°ã®æ¬ ç¹
- ãªãŒããŒãããïŒããã»ã¹ã¯ã¹ã¬ãããããéããããäœæãšåãæ¿ããé ããªããŸãã
- éä¿¡ã®è€éãïŒããã»ã¹éã®éä¿¡ã¯ãã¹ã¬ããéã®éä¿¡ãããè€éã§ãã
- ãªãœãŒã¹ã®æ¶è²»ïŒããã»ã¹ã¯ãã¹ã¬ãããããå€ãã®ã¡ã¢ãªãŒããã®ä»ã®ãªãœãŒã¹ãæ¶è²»ããŸãã
ãã«ãããã»ãã·ã³ã°ã©ã€ãã©ãª
ã»ãšãã©ã®ããã°ã©ãã³ã°èšèªã«ã¯ãããã»ã¹ãäœæããã³ç®¡çããããã®ã©ã€ãã©ãªãçšæãããŠããŸããäŸãšããŠã¯ã次ã®ãã®ããããŸãã
- Python multiprocessingã¢ãžã¥ãŒã«ïŒPythonã§ããã»ã¹ãäœæããã³ç®¡çããããã®åŒ·åãªã¢ãžã¥ãŒã«ã
- Java ProcessBuilderïŒJavaã§å€éšããã»ã¹ãäœæããã³ç®¡çããããã
- C++ forkïŒïŒããã³execïŒïŒïŒC++ã§ããã»ã¹ãäœæããã³å®è¡ããããã®ã·ã¹ãã ã³ãŒã«ã
OpenMP
OpenMPïŒOpen Multi-ProcessingïŒã¯ãå ±æã¡ã¢ãªãŒäžŠåããã°ã©ãã³ã°çšã®APIã§ããCãC ++ãããã³Fortranããã°ã©ã ã䞊ååããããã«äœ¿çšã§ããã³ã³ãã€ã©ãã£ã¬ã¯ãã£ããã©ã€ãã©ãªã«ãŒãã³ãããã³ç°å¢å€æ°ã®ã»ãããæäŸããŸããOpenMPã¯ãã«ãŒãã®äžŠååãªã©ãããŒã¿äžŠåã¿ã¹ã¯ã«ç¹ã«ããé©ããŠããŸãã
OpenMPã®å©ç¹
- 䜿ããããïŒOpenMPã¯æ¯èŒç䜿ãããããã³ãŒãã䞊ååããããã«å¿ èŠãªã³ã³ãã€ã©ãã£ã¬ã¯ãã£ãã¯ãããããã§ãã
- ç§»æ€æ§ïŒOpenMPã¯ãã»ãšãã©ã®äž»èŠãªã³ã³ãã€ã©ããã³ãªãã¬ãŒãã£ã³ã°ã·ã¹ãã ã§ãµããŒããããŠããŸãã
- ã€ã³ã¯ãªã¡ã³ã¿ã«äžŠååïŒOpenMPã䜿çšãããšãã¢ããªã±ãŒã·ã§ã³å šäœãæžãæããããšãªããã³ãŒããã€ã³ã¯ãªã¡ã³ã¿ã«ã«äžŠååã§ããŸãã
OpenMPã®æ¬ ç¹
- å ±æã¡ã¢ãªãŒã®å¶éïŒOpenMPã¯å ±æã¡ã¢ãªãŒã·ã¹ãã çšã«èšèšãããŠããã忣ã¡ã¢ãªãŒã·ã¹ãã ã«ã¯é©ããŠããŸããã
- åæã®ãªãŒããŒãããïŒåæã®ãªãŒããŒãããã¯ãæ éã«ç®¡çããªããšããã©ãŒãã³ã¹ãäœäžãããå¯èœæ§ããããŸãã
MPIïŒã¡ãã»ãŒãžããã·ã³ã°ã€ã³ã¿ãŒãã§ã€ã¹ïŒ
MPIïŒã¡ãã»ãŒãžããã·ã³ã°ã€ã³ã¿ãŒãã§ã€ã¹ïŒã¯ãããã»ã¹éã®ã¡ãã»ãŒãžããã·ã³ã°éä¿¡ã®æšæºã§ããã¯ã©ã¹ã¿ãŒãã¹ãŒããŒã³ã³ãã¥ãŒã¿ãŒãªã©ã®åæ£ã¡ã¢ãªãŒã·ã¹ãã ã§ã®äžŠåããã°ã©ãã³ã°ã«åºã䜿çšãããŠããŸããMPIã䜿çšãããšãããã»ã¹ã¯ã¡ãã»ãŒãžãéåä¿¡ããŠãäœæ¥ãéä¿¡ããã³èª¿æŽã§ããŸãã
MPIã®å©ç¹
- ã¹ã±ãŒã©ããªãã£ïŒMPIã¯ã忣ã¡ã¢ãªãŒã·ã¹ãã ã®å€æ°ã®ããã»ããµã«ã¹ã±ãŒãªã³ã°ã§ããŸãã
- æè»æ§ïŒMPIã¯ãè€éãªäžŠåã¢ã«ãŽãªãºã ãå®è£ ããããã«äœ¿çšã§ããè±å¯ãªéä¿¡ããªããã£ãã®ã»ãããæäŸããŸãã
MPIã®æ¬ ç¹
- è€éãïŒMPIããã°ã©ãã³ã°ã¯ãå ±æã¡ã¢ãªãŒããã°ã©ãã³ã°ãããè€éã«ãªãå¯èœæ§ããããŸãã
- éä¿¡ã®ãªãŒããŒãããïŒéä¿¡ã®ãªãŒããŒãããã¯ãMPIã¢ããªã±ãŒã·ã§ã³ã®ããã©ãŒãã³ã¹ã«å€§ããªåœ±é¿ãäžããå¯èœæ§ããããŸãã
å®è·µçãªäŸãšã³ãŒãã¹ãããã
äžèšã§èª¬æããæŠå¿µã説æããããã«ãããã€ãã®å®è·µçãªäŸãšãããŸããŸãªããã°ã©ãã³ã°èšèªã§ã®ã³ãŒãã¹ãããããæ€èšããŸãããã
Python Multiprocessingã®äŸ
ãã®äŸã§ã¯ãPythonã®multiprocessingã¢ãžã¥ãŒã«ã䜿çšããŠãæ°å€ã®ãªã¹ãã®2ä¹åã䞊è¡ããŠèšç®ããæ¹æ³ã瀺ããŸãã
import multiprocessing
import time
def square_sum(numbers):
"""Calculates the sum of squares of a list of numbers."""
total = 0
for n in numbers:
total += n * n
return total
if __name__ == '__main__':
numbers = list(range(1, 1001))
num_processes = multiprocessing.cpu_count() # Get the number of CPU cores
chunk_size = len(numbers) // num_processes
chunks = [numbers[i:i + chunk_size] for i in range(0, len(numbers), chunk_size)]
with multiprocessing.Pool(processes=num_processes) as pool:
start_time = time.time()
results = pool.map(square_sum, chunks)
end_time = time.time()
total_sum = sum(results)
print(f"Total sum of squares: {total_sum}")
print(f"Execution time: {end_time - start_time:.4f} seconds")
ãã®äŸã§ã¯ãæ°å€ã®ãªã¹ãããã£ã³ã¯ã«åå²ããåãã£ã³ã¯ãåå¥ã®ããã»ã¹ã«å²ãåœãŠãŸããmultiprocessing.Poolã¯ã©ã¹ã¯ãããã»ã¹ã®äœæãšå®è¡ã管çããŸãã
Java Concurrencyã®äŸ
ãã®äŸã§ã¯ãJavaã®Concurrency APIã䜿çšããŠãåæ§ã®ã¿ã¹ã¯ã䞊è¡ããŠå®è¡ããæ¹æ³ã瀺ããŸãã
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
public class SquareSumTask implements Callable<Long> {
private final List<Integer> numbers;
public SquareSumTask(List<Integer> numbers) {
this.numbers = numbers;
}
@Override
public Long call() {
long total = 0;
for (int n : numbers) {
total += n * n;
}
return total;
}
public static void main(String[] args) throws Exception {
List<Integer> numbers = new ArrayList<>();
for (int i = 1; i <= 1000; i++) {
numbers.add(i);
}
int numThreads = Runtime.getRuntime().availableProcessors(); // Get the number of CPU cores
ExecutorService executor = Executors.newFixedThreadPool(numThreads);
int chunkSize = numbers.size() / numThreads;
List<Future<Long>> futures = new ArrayList<>();
for (int i = 0; i < numThreads; i++) {
int start = i * chunkSize;
int end = (i == numThreads - 1) ? numbers.size() : (i + 1) * chunkSize;
List<Integer> chunk = numbers.subList(start, end);
SquareSumTask task = new SquareSumTask(chunk);
futures.add(executor.submit(task));
}
long totalSum = 0;
for (Future<Long> future : futures) {
totalSum += future.get();
}
executor.shutdown();
System.out.println("Total sum of squares: " + totalSum);
}
}
ãã®äŸã§ã¯ãExecutorServiceã䜿çšããŠã¹ã¬ããã®ããŒã«ã管çããŸããåã¹ã¬ããã¯ãæ°å€ã®ãªã¹ãã®äžéšã®2ä¹åãèšç®ããŸããFutureã€ã³ã¿ãŒãã§ã€ã¹ã䜿çšãããšãéåæã¿ã¹ã¯ã®çµæãååŸã§ããŸãã
C++ OpenMPã®äŸ
ãã®äŸã§ã¯ãOpenMPã䜿çšããŠC++ã®ã«ãŒãã䞊ååããæ¹æ³ã瀺ããŸãã
#include <iostream>
#include <vector>
#include <numeric>
#include <omp.h>
int main() {
int n = 1000;
std::vector<int> numbers(n);
std::iota(numbers.begin(), numbers.end(), 1);
long long total_sum = 0;
#pragma omp parallel for reduction(+:total_sum)
for (int i = 0; i < n; ++i) {
total_sum += (long long)numbers[i] * numbers[i];
}
std::cout << "Total sum of squares: " << total_sum << std::endl;
return 0;
}
#pragma omp parallel forãã£ã¬ã¯ãã£ãã¯ãã³ã³ãã€ã©ã«ã«ãŒãã䞊ååããããã«æç€ºããŸããreduction(+:total_sum)å¥ã¯ãtotal_sum倿°ããã¹ãŠã®ã¹ã¬ããã§çž®å°ããŠãæçµçµæãæ£ããããšãä¿èšŒããå¿
èŠãããããšãæå®ããŸãã
CPU䜿çšçãç£èŠããããã®ããŒã«
CPU䜿çšçãç£èŠããããšã¯ãã¢ããªã±ãŒã·ã§ã³ããã«ãã³ã¢CPUãã©ãã ãæå¹ã«æŽ»çšããŠããããçè§£ããããã«äžå¯æ¬ ã§ããããŸããŸãªãªãã¬ãŒãã£ã³ã°ã·ã¹ãã ã§CPU䜿çšçãç£èŠããããã«å©çšã§ããããŒã«ãããã€ããããŸãã
- LinuxïŒ
topãhtopãvmstatãiostatãperf - WindowsïŒã¿ã¹ã¯ãããŒãžã£ãŒããªãœãŒã¹ã¢ãã¿ãŒãããã©ãŒãã³ã¹ã¢ãã¿ãŒ
- macOSïŒã¢ã¯ãã£ããã£ã¢ãã¿ãŒã
top
ãããã®ããŒã«ã¯ãCPU䜿çšçãã¡ã¢ãªãŒäœ¿çšéããã£ã¹ã¯I / Oãããã³ãã®ä»ã®ã·ã¹ãã ã¡ããªãã¯ã«é¢ããæ å ±ãæäŸããŸãããããã¯ãããã«ããã¯ãç¹å®ããããåªããããã©ãŒãã³ã¹ã®ããã«ã¢ããªã±ãŒã·ã§ã³ãæé©åããã®ã«åœ¹ç«ã¡ãŸãã
ãã«ãã³ã¢CPUãå©çšããããã®ãã¹ããã©ã¯ãã£ã¹
ãã«ãã³ã¢CPUã广çã«å©çšããã«ã¯ã次ã®ãã¹ããã©ã¯ãã£ã¹ãæ€èšããŠãã ããã
- 䞊ååå¯èœãªã¿ã¹ã¯ã®ç¹å®ïŒã¢ããªã±ãŒã·ã§ã³ãåæããŠã䞊è¡ããŠå®è¡ã§ããã¿ã¹ã¯ãç¹å®ããŸãã
- é©åãªãã¯ããã¯ã®éžæïŒã¿ã¹ã¯ã®ç¹æ§ãšã·ã¹ãã ã¢ãŒããã¯ãã£ã«åºã¥ããŠãé©åãªäžŠåããã°ã©ãã³ã°ãã¯ããã¯ïŒã¹ã¬ããã£ã³ã°ããã«ãããã»ãã·ã³ã°ãOpenMPãMPIïŒãéžæããŸãã
- åæã®ãªãŒããŒãããã®æå°åïŒãªãŒããŒããããæå°éã«æããããã«ãã¹ã¬ãããŸãã¯ããã»ã¹éã§å¿ èŠãªåæã®éãæžãããŸãã
- åœã®å ±æã®åé¿ïŒã¹ã¬ãããåããã£ãã·ã¥ã©ã€ã³ã«ååšããç°ãªãããŒã¿é ç®ã«ã¢ã¯ã»ã¹ããçŸè±¡ã§ããåœã®å ±æã«æ³šæããŠãã ãããããã«ãããäžèŠãªãã£ãã·ã¥ã®ç¡å¹åãšããã©ãŒãã³ã¹ã®äœäžã«ã€ãªãããŸãã
- ã¯ãŒã¯ããŒãã®ãã©ã³ã¹ïŒãã¹ãŠã®ã³ã¢ã«ã¯ãŒã¯ããŒããåçã«åæ£ããŠãä»ã®ã³ã¢ãéè² è·ã«ãªã£ãŠãããšãã«ã¢ã€ãã«ç¶æ ã®ã³ã¢ããªãããã«ããŸãã
- ããã©ãŒãã³ã¹ã®ç£èŠïŒCPU䜿çšçããã®ä»ã®ããã©ãŒãã³ã¹ã¡ããªãã¯ãç¶ç¶çã«ç£èŠããŠãããã«ããã¯ãç¹å®ããã¢ããªã±ãŒã·ã§ã³ãæé©åããŸãã
- ã¢ã ããŒã«ã®æ³åãšã°ã¹ã¿ããœã³ã®æ³åã®æ€èšïŒã³ãŒãã®ã·ãªã¢ã«éšåãšåé¡ãµã€ãºã®ã¹ã±ãŒã©ããªãã£ã«åºã¥ããŠãã¹ããŒãã¢ããã®çè«çãªéçãçè§£ããŸãã
- ãããã¡ã€ãªã³ã°ããŒã«ã®äœ¿çšïŒãããã¡ã€ãªã³ã°ããŒã«ãå©çšããŠãã³ãŒãã®ããã©ãŒãã³ã¹ããã«ããã¯ãšãããã¹ããããç¹å®ããŸãã äŸã«ã¯ãIntel VTune AmplifierãperfïŒLinuxïŒãããã³Xcode InstrumentsïŒmacOSïŒãå«ãŸããŸãã
ã°ããŒãã«ãªèæ ®äºé ãšåœéå
ã°ããŒãã«ãªãªãŒãã£ãšã³ã¹åãã®ã¢ããªã±ãŒã·ã§ã³ãéçºããå Žåã¯ãåœéåãšããŒã«ãªãŒãŒã·ã§ã³ãæ€èšããããšãéèŠã§ãã ããã«ã¯ã以äžãå«ãŸããŸãã
- æåãšã³ã³ãŒãã£ã³ã°ïŒUnicodeïŒUTF-8ïŒã䜿çšããŠãå¹ åºãæåããµããŒãããŸãã
- ããŒã«ãªãŒãŒã·ã§ã³ïŒã¢ããªã±ãŒã·ã§ã³ãããŸããŸãªèšèªãå°åãæåã«é©å¿ãããŸãã
- ã¿ã€ã ãŸãŒã³ïŒã¿ã€ã ãŸãŒã³ãæ£ããåŠçããŠãç°ãªãå Žæã«ãããŠãŒã¶ãŒã«å¯ŸããŠæ¥ä»ãšæå»ãæ£ç¢ºã«è¡šç€ºãããããã«ããŸãã
- é貚ïŒè€æ°ã®é貚ããµããŒãããé貚èšå·ãé©åã«è¡šç€ºããŸãã
- æ°å€ãšæ¥ä»ã®åœ¢åŒïŒããŸããŸãªãã±ãŒã«ã«é©åãªæ°å€ãšæ¥ä»ã®åœ¢åŒã䜿çšããŸãã
ãããã®èæ ®äºé ã¯ãã¢ããªã±ãŒã·ã§ã³ãäžçäžã®ãŠãŒã¶ãŒã«ã¢ã¯ã»ã¹å¯èœã§äœ¿ããããããšãä¿èšŒããããã«äžå¯æ¬ ã§ãã
çµè«
ãã«ãã³ã¢CPUã¯ã䞊ååŠçãéããŠå€§ããªããã©ãŒãã³ã¹åäžã®å¯èœæ§ãæäŸããŸãããã®ã¬ã€ãã§èª¬æããæŠå¿µãšãã¯ããã¯ãçè§£ããããšã«ãããéçºè ããã³ã·ã¹ãã 管çè ã¯ããã«ãã³ã¢CPUã广çã«å©çšããŠãã¢ããªã±ãŒã·ã§ã³ã®ããã©ãŒãã³ã¹ãå¿çæ§ãããã³ã¹ã±ãŒã©ããªãã£ãåäžãããããšãã§ããŸããé©åãªäžŠåããã°ã©ãã³ã°ã¢ãã«ã®éžæãããCPU䜿çšçã®æ éãªç£èŠãããã³ã°ããŒãã«ãªèŠçŽ ã®èæ ®ãŸã§ã仿¥ã®å€æ§ã§èŠæ±ã®å³ããã³ã³ãã¥ãŒãã£ã³ã°ç°å¢ã§ãã«ãã³ã¢ããã»ããµã®å¯èœæ§ãæå€§éã«åŒãåºãã«ã¯ãå šäœè«çãªã¢ãããŒããäžå¯æ¬ ã§ããå®éã®ããã©ãŒãã³ã¹ããŒã¿ã«åºã¥ããŠã³ãŒããç¶ç¶çã«ãããã¡ã€ã«ããŠæé©åãã䞊ååŠçãã¯ãããžãŒã®ææ°ã®é²æ©ã«ã€ããŠåžžã«æ å ±ãå ¥æããŠãã ããã