ããã°ãã¯
ã³ãŒã¹
ãC ++ Developerãããã䞊åã¢ã«ãŽãªãºã ã«é¢ããå°èŠæš¡ã§è峿·±ãç ç©¶
ãæäŸããŸãã
è¡ãã
C ++ 17ã®äžŠåã¢ã«ãŽãªãºã ã®åºçŸã«ããããã³ã³ãã¥ãŒãã£ã³ã°ãã³ãŒããç°¡åã«æŽæ°ãã䞊åå®è¡ã®ã¡ãªããã享åã§ããŸãã ãã®èšäºã§ã¯ãç¬ç«ããã³ã³ãã¥ãŒãã£ã³ã°ã®æŠå¿µãèªç¶ã«æããã«ããSTLã¢ã«ãŽãªãºã ãæ€èšããŸãã 10ã³ã¢ããã»ããµã§10åã®é«éåãæåŸ
ã§ããŸããïŒ ãããšããã£ãšïŒ ãã以äžïŒ ããã«ã€ããŠè©±ããŸãããã
䞊åã¢ã«ãŽãªãºã ã®ç޹ä»
C ++ 17ã¯ãã»ãšãã©ã®ã¢ã«ãŽãªãºã ã«å¯ŸããŠå®è¡ããªã·ãŒèšå®ãæäŸããŸãã
- sequenced_policy-䞊åã¢ã«ãŽãªãºã ã®äžŠåæ§ããã³äžŠåã¢ã«ãŽãªãºã å®è¡ã®äžŠååãäžå¯èœã§ãããšããèŠä»¶ãæé€ããããã«äžæã®ã¿ã€ããšããŠäœ¿çšãããå®è¡ããªã·ãŒã®ã¿ã€ãïŒå¯Ÿå¿ããã°ããŒãã«ãªããžã§ã¯ãã¯
std::execution::seq
; - parallel_policy-䞊åã¢ã«ãŽãªãºã ã®ãªãŒããŒããŒããæé€ãã䞊åã¢ã«ãŽãªãºã ã®å®è¡ã®äžŠååãå¯èœã§ããããšã瀺ãããã«äžæã®ã¿ã€ããšããŠäœ¿çšãããå®è¡ããªã·ãŒã®ã¿ã€ãïŒå¯Ÿå¿ããã°ããŒãã«ãªããžã§ã¯ãã¯
std::execution::par
; - parallel_unsequenced_policy-䞊åã¢ã«ãŽãªãºã ã®ãªãŒããŒããŒããæé€ãã䞊åã¢ã«ãŽãªãºã å®è¡ã®äžŠååãšãã¯ãã«åãå¯èœã§ããããšã瀺ãããã«äžæã®ã¿ã€ããšããŠäœ¿çšãããå®è¡ããªã·ãŒã®ã¿ã€ãïŒå¯Ÿå¿ããã°ããŒãã«ãªããžã§ã¯ãã¯
std::execution::par_unseq
;
ç°¡åã«ïŒ
- ã¢ã«ãŽãªãºã ã®é 次å®è¡ã«ã¯
std::execution::seq
ã䜿çšããŸãã - ã¢ã«ãŽãªãºã ã®äžŠåå®è¡ã«ã¯
std::execution::par
ã䜿çšããŸãïŒéåžžãããã€ãã®Thread Poolå®è£
ïŒã¹ã¬ããããŒã«ïŒã䜿çšïŒã std::execution::par_unseq
ã䜿çšããŠããã¯ãã«ã³ãã³ãïŒSSEãAVXãªã©ïŒã䜿çšã§ããã¢ã«ãŽãªãºã ã®äžŠåå®è¡ãè¡ããŸãã
ç°¡åãªäŸãšããŠã
std::sort
callã䞊åã«åŒã³åºããŸãïŒ
std::sort(std::execution::par, myVec.begin(), myVec.end());
ã¢ã«ãŽãªãºã ã«äžŠåå®è¡ãã©ã¡ãŒã¿ãŒã远å ããã®ãã©ãã»ã©ç°¡åãã«æ³šæããŠãã ããïŒ ããããããã©ãŒãã³ã¹ã倧å¹
ã«æ¹åãããã®ã§ããããïŒ é床ãäžãããŸããïŒ ãããšãæžéããããŸããïŒ
䞊åstd::transform
ãã®èšäºã§ã¯ãä»ã®äžŠåã¡ãœããïŒ
std::transform_reduce
ã
for_each
ã
scan
ã
sort
...ãšãšãã«ïŒã®åºç€ãšãªãå¯èœæ§ããã
std::transform
ã¢ã«ãŽãªãºã ã«æ³šæãæããããšæããŸãã
ãã¹ãã³ãŒãã¯ã次ã®ãã³ãã¬ãŒãã«åŸã£ãŠæ§ç¯ãããŸãã
std::transform(execution_policy,
ElementOperation
颿°ã«åæã¡ãœããããªããšä»®å®ããŸãããã®å Žåãã³ãŒãã«ã¯äžŠåå®è¡ãŸãã¯ãã¯ãã«åã®å¯èœæ§ããããŸãã åèŠçŽ ã®èšç®ã¯ç¬ç«ããŠãããé åºã¯éèŠã§ã¯ãããŸããããã®ãããå®è£
ã¯èŠçŽ ã®ç¬ç«ããåŠçã®ããã«è€æ°ã®ã¹ã¬ãããïŒã¹ã¬ããããŒã«å
ã«ïŒçæã§ããŸãã
次ã®ããšã詊ããŠã¿ããïŒ
- ãã¯ãã«å Žã®ãµã€ãºã倧ãããå°ããã
- ã»ãšãã©ã®æéãã¡ã¢ãªã«ã¢ã¯ã»ã¹ããåçŽãªå€æã
- ããå€ãã®ç®è¡ïŒALUïŒæäœã
- ããçŸå®çãªã·ããªãªã®ALUã
ã芧ã®ãšããã䞊åã¢ã«ãŽãªãºã ã䜿çšããã®ã«ãè¯ããèŠçŽ ã®æ°ã ãã§ãªããããã»ããµãå æããALUæäœããã¹ãããŸãã
ãœãŒãã环ç©ïŒstd :: reduceã®åœ¢åŒïŒãªã©ã®ä»ã®ã¢ã«ãŽãªãºã ã䞊åå®è¡ãæäŸããŸãããçµæãèšç®ããããã«ããå€ãã®äœæ¥ãå¿
èŠã§ãã ãããã£ãŠãããããå¥ã®èšäºã®åè£ãšèŠãªããŸãã
ãã³ãããŒã¯ããŒã
ç§ã®ãã¹ãã§ã¯ãVisual Studio 2017ã15.8ã䜿çšããŸããããã¯ãçŸæç¹ïŒ2018幎11æïŒã§äººæ°ã®ããã³ã³ãã€ã©/ STLå®è£
ã®å¯äžã®å®è£
ã§ããããã§ãïŒéäžGCCïŒïŒã ããã«ã
execution::par_unseq
MSVCã§ã¯äœ¿çšã§ããªãããã
execution::par
ã®ã¿ã«çŠç¹ãåãããŸããïŒ
execution::par
ãšåæ§ã«æ©èœããŸãïŒã
2ã€ã®ã³ã³ãã¥ãŒã¿ãŒããããŸãã
- i7 8700-PCãWindows 10ãi7 8700-3.2 GHzã6ã³ã¢/ 12ã¹ã¬ããïŒãã€ããŒã¹ã¬ããã£ã³ã°ïŒ;
- i7 4720-ã©ããããããWindows 10ãi7 4720ã2.6 GHzã4ã³ã¢/ 8ã¹ã¬ããïŒãã€ããŒã¹ã¬ããã£ã³ã°ïŒã
ã³ãŒãã¯x64ã§ã³ã³ãã€ã«ãããRelease moreãèªåãã¯ãã«åã¯ããã©ã«ãã§æå¹ã«ãªã£ãŠããŸããã³ãã³ãã®æ¡åŒµã»ããïŒSSE2ïŒãšOpenMPïŒ2.0ïŒãå«ãŸããŠããŸãã
ã³ãŒãã¯ç§ã®githubã«ãããŸãïŒ
github / fenbf / ParSTLTests / TransformTests / TransformTests.cppOpenMPïŒ2.0ïŒã®å Žåãã«ãŒãã«å¯ŸããŠã®ã¿äžŠååŠçã䜿çšããŸãã
#pragma omp parallel for for (int i = 0; ...)
ã³ãŒãã5åå®è¡ããæå°ã®çµæã確èªããŸãã
èŠå ïŒçµæã¯å€§ãŸããªèгå¯çµæã®ã¿ãåæ ããŠãããããå®çšŒåç°å¢ã§äœ¿çšããåã«ã·ã¹ãã /æ§æã確èªããŠãã ããã èŠä»¶ãšç°å¢ã¯ç§ã®èŠä»¶ãšç°ãªãå ŽåããããŸãããã®æçš¿ã§ MSVCã®å®è£
ã«ã€ããŠè©³ããèªãããšãã§ããŸãã ãããŠãCppCon 2018
ã«é¢ãããã«ã»ãªããŒã«ã®ææ°
ã¬ããŒãã§ãïŒãã«ã¯MSVCã§ãã©ã¬ã«STLãå®è£
ããŸããïŒã
ããŠãç°¡åãªäŸããå§ããŸãããïŒ
ç°¡åãªå€æå
¥åãã¯ãã«ã«éåžžã«ç°¡åãªæäœãé©çšããå ŽåãèããŠãã ããã èŠçŽ ã®ã³ããŒãŸãã¯ä¹ç®ãå¯èœã§ãã
äŸïŒ
std::transform(std::execution::par, vec.begin(), vec.end(), out.begin(), [](double v) { return v * 2.0; } );
ã³ã³ãã¥ãŒã¿ãŒã«6ã³ã¢ãŸãã¯4ã³ã¢ããããŸãã4..6åã®é 次å®è¡ãæåŸ
ã§ããŸããïŒ ããã«ç§ã®çµæããããŸãïŒããªç§åäœã®æéïŒïŒ
éå¶ | ãã¯ã¿ãŒãµã€ãº | i7 4720ïŒ4ã³ã¢ïŒ | i7 8700ïŒ6ã³ã¢ïŒ |
---|
å®è¡:: seq | 10k | 0.002763 | 0.001924 |
å®è¡::ã㌠| 10k | 0.009869 | 0.008983 |
ã®openmp䞊å | 10k | 0.003158 | 0.002246 |
å®è¡:: seq | 10äž | 0.051318 | 0.028872 |
å®è¡::ã㌠| 10äž | 0.043028 | 0.025664 |
ã®openmp䞊å | 10äž | 0.022501 | 0.009624 |
å®è¡:: seq | 1000k | 1.69508 | 0.52419 |
å®è¡::ã㌠| 1000k | 1.65561 | 0.359619 |
ã®openmp䞊å | 1000k | 1.50678 | 0.344863 |
ããé«éãªãã·ã³ã§ã¯ãããã©ãŒãã³ã¹ã®åäžã«æ°ä»ãã«ã¯çŽ100äžã®èŠçŽ ãå¿
èŠã§ããããšãããããŸãã äžæ¹ãç§ã®ã©ãããããã§ã¯ããã¹ãŠã®äžŠåå®è£
ãé
ããªããŸããã
ãããã£ãŠãèŠçŽ ã®æ°ãå¢ããŠãããã®ãããªå€æã䜿çšãããšãããã©ãŒãã³ã¹ã倧å¹
ã«åäžããããšã«æ°ä»ãããšã¯å°é£ã§ãã
ãªãããã§ããïŒ
æäœã¯åºæ¬çãªãã®ã§ãããããããã»ããµã³ã¢ã¯æ°ãµã€ã¯ã«ã®ã¿ã䜿çšããŠã»ãŒç¬æã«åŒã³åºãããšãã§ããŸãã ãã ããããã»ããµã³ã¢ã¯ã¡ã€ã³ã¡ã¢ãªã®åŸ
æ©ã«ããå€ãã®æéãè²»ãããŸãã ãããã£ãŠããã®å Žåãã»ãšãã©ã®å Žåãèšç®ãè¡ããã«åŸ
æ©ããŸãã
ã¡ã¢ãªå
ã®å€æ°ã®èªã¿åããšæžã蟌ã¿ã¯ããã£ãã·ã¥ãããŠããå Žåã¯çŽ2ã3ãµã€ã¯ã«ããã£ãã·ã¥ãããŠããªãå Žåã¯æ°çŸãµã€ã¯ã«ããããŸããhttps://www.agner.org/optimize/optimizing_cpp.pdfã¢ã«ãŽãªãºã ãã¡ã¢ãªã«äŸåããŠããå Žåã䞊åèšç®ã«ããããã©ãŒãã³ã¹ã®åäžã¯æåŸ
ã§ããªãããšã«å€§ãŸãã«æ³šæã§ããŸãã
ãã®ä»ã®èšç®ã¡ã¢ãªåž¯åå¹
ã¯éåžžã«éèŠã§ãããç©äºã®é床ã«åœ±é¿ãäžããå¯èœæ§ããããã...åèŠçŽ ã«åœ±é¿ããèšç®éãå¢ãããŸãããã
ã¢ã€ãã¢ã¯ãã¡ã¢ãªãåŸ
ã€æéãç¡é§ã«ãããããããã»ããµãµã€ã¯ã«ã䜿çšããæ¹ãè¯ããšããããšã§ãã
ãŸããäžè§é¢æ°ã䜿çšããŸããããšãã°ã
sqrt(sin*cos)
ïŒãããã¯ããã»ããµãå æããããã®ãæé©ã§ãªã圢åŒã®æ¡ä»¶ä»ãèšç®ã§ãïŒã
sqrt
ã
sin
ãããã³
cos
ã䜿çšããŸããããã¯ã
sqrt
ããšã«æå€§20åãäžè§é¢æ°ããšã«æå€§100åãåãããšãã§ããŸãã ãã®èšç®éã¯ãã¡ã¢ãªã¢ã¯ã»ã¹é
å»¶ãã«ããŒã§ããŸãã
ããŒã ã®é
å»¶ã®è©³çްã«ã€ããŠã¯
ãAgner Foghã«ããåªãã
ããã©ãŒãã³ã¹ã¬ã€ããåç
§ããŠãã ããã
ãã³ãããŒã¯ã³ãŒãã¯æ¬¡ã®ãšããã§ãã
std::transform(std::execution::par, vec.begin(), vec.end(), out.begin(), [](double v) { return std::sqrt(std::sin(v)*std::cos(v)); } );
ãããŠä»äœïŒ 以åã®è©Šã¿ãããããã©ãŒãã³ã¹ãåäžããããšãæåŸ
ã§ããŸããïŒ
以äžã«çµæã瀺ããŸãïŒããªç§åäœã®æéïŒïŒ
éå¶ | ãã¯ã¿ãŒãµã€ãº | i7 4720ïŒ4ã³ã¢ïŒ | i7 8700ïŒ6ã³ã¢ïŒ |
---|
å®è¡:: seq | 10k | 0.105005 | 0.070577 |
å®è¡::ã㌠| 10k | 0.055661 | 0.03176 |
ã®openmp䞊å | 10k | 0.096321 | 0.024702 |
å®è¡:: seq | 10äž | 1.08755 | 0.707048 |
å®è¡::ã㌠| 10äž | 0.259354 | 0.17195 |
ã®openmp䞊å | 10äž | 0.898465 | 0.189915 |
å®è¡:: seq | 1000k | 10.5159 | 7.16254 |
å®è¡::ã㌠| 1000k | 2.44472 | 1.10099 |
ã®openmp䞊å | 1000k | 4.78681 | 1.89017 |
æåŸã«ãè¯ãæ°åãããã€ããããŸã:)
1000åã®èŠçŽ ïŒããã«ã¯è¡šç€ºãããŠããŸããïŒã®å Žåã䞊åèšç®æéãšé 次èšç®æéã¯é¡äŒŒããŠããããã1000åãè¶
ããèŠçŽ ã§ã¯ã䞊åããŒãžã§ã³ã®æ¹åãèŠãããŸãã
10äžåã®èŠçŽ ã®å Žåãé«éãªã³ã³ãã¥ãŒã¿ãŒã§ã®çµæã¯ãã·ãªã¢ã«ããŒãžã§ã³ã®ã»ãŒ9åã§ãïŒOpenMPããŒãžã§ã³ãšåæ§ïŒã
100äžèŠçŽ ã®æå€§ããŒãžã§ã³ã§ã¯ãçµæã¯5ã8åé«éã§ãã
ãã®ãããªèšç®ã§ã¯ãããã»ããµã³ã¢ã®æ°ã«å¿ããŠãç·åœ¢ãå éãéæããŸããã ããã¯äºæ³ãããããšã§ããã
ãã¬ãã«ããã³3次å
ãã¯ãã«äžèšã®ã»ã¯ã·ã§ã³ã§ã¯ããçºæããããèšç®ã䜿çšããŸããããå®éã®ã³ãŒãã¯ã©ãã§ããïŒ
æ»ããã§å¹³ããªè¡šé¢ããã®å
ã®åå°ãšæ²çãèšè¿°ãããã¬ãã«æ¹çšåŒãè§£ããŸãããã ããã¯ã3Dã²ãŒã ã§ãªã¢ã«ãªç
§æãçæããäžè¬çãªæ¹æ³ã§ãã

ãŠã£ãã¡ãã£ã¢ããã®åçè¯ãäŸãšããŠã
ãã®èª¬æãšå®è£
ãèŠã€ããŸããã
GLMã©ã€ãã©ãªã®äœ¿çšã«ã€ããŠç¬èªã®å®è£
ãäœæãã代ããã«
ãglm libraryã䜿çšããŸã
ã ã OpenGlãããžã§ã¯ãã§ãã䜿çšããŸãã
ã©ã€ãã©ãªãŒã¯
Conan Package Managerãä»ããŠç°¡åã«ã¢ã¯ã»ã¹ã§ãããããããã䜿çšããŸãã ããã±ãŒãžãžã®
ãªã³ã¯ ã
ã³ãã³ãã¡ã€ã«ïŒ
[requires] glm/0.9.9.1@g-truc/stable [generators] visual_studio
ã©ã€ãã©ãªãã€ã³ã¹ããŒã«ããã³ãã³ãã©ã€ã³ïŒVisual Studioãããžã§ã¯ãã§äœ¿çšã§ããpropsãã¡ã€ã«ãçæããŸãïŒïŒ
conan install . -s build_type=Release -if build_release_x64 -s arch=x86_64
ã©ã€ãã©ãªã¯ããããŒã§æ§æãããŠãããããå¿
èŠã«å¿ããŠæåã§ããŠã³ããŒãã§ããŸãã
å®éã®ã³ãŒããšãã³ãããŒã¯scratchapixel.comããglmã®ã³ãŒããé©åãããŸããïŒ
ãã®ã³ãŒãã¯ãããã»ããµãå®è¡ããããšãã§ããããã«ãããã€ãã®æ°åŠåœä»€ãã¹ã«ã©ãŒç©ãä¹ç®ãé€ç®ã䜿çšããŸãã doubleãã¯ãã«ã®ä»£ããã«ã4ã€ã®èŠçŽ ã®ãã¯ãã«ã䜿çšããŠã䜿çšãããã¡ã¢ãªã®éãå¢ãããŸãã
ãã³ãããŒã¯ïŒ
std::transform(std::execution::par, vec.begin(), vec.end(), vecNormals.begin(),
çµæã¯æ¬¡ã®ãšããã§ãïŒããªç§åäœïŒïŒ
éå¶ | ãã¯ã¿ãŒãµã€ãº | i7 4720ïŒ4ã³ã¢ïŒ | i7 8700ïŒ6ã³ã¢ïŒ |
---|
å®è¡:: seq | 1k | 0.032764 | 0.016361 |
å®è¡::ã㌠| 1k | 0.031186 | 0.028551 |
ã®openmp䞊å | 1k | 0.005526 | 0.007699 |
å®è¡:: seq | 10k | 0.246722 | 0.169383 |
å®è¡::ã㌠| 10k | 0.090794 | 0.067048 |
ã®openmp䞊å | 10k | 0.049739 | 0.029835 |
å®è¡:: seq | 10äž | 2.49722 | 1.69768 |
å®è¡::ã㌠| 10äž | 0.530157 | 0.283268 |
ã®openmp䞊å | 10äž | 0.495024 | 0.291609 |
å®è¡:: seq | 1000k | 08.2528 | 16.9457 |
å®è¡::ã㌠| 1000k | 5.15235 | 2.33768 |
ã®openmp䞊å | 1000k | 5.11801 | 2.95908 |
ãå®éã®ãã³ã³ãã¥ãŒãã£ã³ã°ã§ã¯ã䞊åã¢ã«ãŽãªãºã ãåªããããã©ãŒãã³ã¹ãæäŸããããšãããããŸãã 2å°ã®Windowsãã·ã³ã§ãã®ãããªæäœãè¡ããšãã³ã¢ã®æ°ã«ã»ãŒç·åœ¢ã«äŸåããé«éåãå®çŸããŸããã
ãã¹ãŠã®ãã¹ãã§ãOpenMPãš2ã€ã®å®è£
ïŒMSVCãšOpenMPãåæ§ã«æ©èœããïŒã®çµæã瀺ããŸããã
ãããã«ãã®èšäºã§ã¯ã䞊åã³ã³ãã¥ãŒãã£ã³ã°ãšäžŠåã¢ã«ãŽãªãºã ã䜿çšãã3ã€ã®ã±ãŒã¹ãæ€èšããŸããã æšæºã¢ã«ãŽãªãºã ãstd :: execution :: parããŒãžã§ã³ã«çœ®ãæããããšã¯éåžžã«é
åçã«æãããããããŸããããããã¯åžžã«è¡ã䟡å€ããããšã¯éããŸããïŒ ã¢ã«ãŽãªãºã å
ã§äœ¿çšããåæäœã¯ç°ãªãåäœãããå Žåããããããã»ããµãŸãã¯ã¡ã¢ãªã«ããäŸåããŸãã ãããã£ãŠãå倿Žãåå¥ã«æ€èšããŠãã ããã
èŠããŠããã¹ãããšïŒ
- ã©ã€ãã©ãªã¯äžŠåå®è¡ãæºåããå¿
èŠããããããéåžžã䞊åå®è¡ã¯é 次å®è¡ãããå€ãã®ããšãè¡ããŸãã
- èŠçŽ ã®æ°ã ãã§ãªããããã»ããµãå æããŠããåœä»€ã®æ°ãéèŠã§ãã
- äºãã«ç¬ç«ããã¿ã¹ã¯ãä»ã®å
±æãªãœãŒã¹ã䜿çšããæ¹ãé©åã§ãã
- 䞊åã¢ã«ãŽãªãºã ã¯ãäœæ¥ãåå¥ã®ã¹ã¬ããã«åå²ããç°¡åãªæ¹æ³ãæäŸããŸãã
- æäœãã¡ã¢ãªã«äŸåããŠããå Žåãããã©ãŒãã³ã¹ã®åäžã¯æåŸ
ã§ããŸããããŸããå Žåã«ãã£ãŠã¯ãã¢ã«ãŽãªãºã ãé
ããªãå¯èœæ§ããããŸãã
- é©åãªããã©ãŒãã³ã¹ã®æ¹åãåŸãã«ã¯ãåžžã«ååé¡ã®ã¿ã€ãã³ã°ã枬å®ããŸããå Žåã«ãã£ãŠã¯ãçµæãå®å
šã«ç°ãªãå ŽåããããŸãã
ãã®èšäºãæ¯æŽããŠãããJFTã«æè¬ããŸãïŒ
䞊åã¢ã«ãŽãªãºã ã«é¢ããä»ã®æ
å ±æºã«ã泚æããŠãã ããïŒ
䞊åã¢ã«ãŽãªãºã ã«é¢é£ããå¥ã®èšäºãã芧ãã ããïŒ
Intel Parallel STLãšC ++ 17䞊åã¢ã«ãŽãªãºã ã§ããã©ãŒãã³ã¹ãåäžãããæ¹æ³çµãã
ç§ãã¡ã¯ã³ã¡ã³ãã質åãåŸ
ã£ãŠããŸãããããã¯ããã
éããŠãããã¢ã® å
çã«æ®ãããšãã§ããŸãã