ããã«ã¡ã¯ãæ¯æãã«ãã ããªã話ããã¾ãã
ããã¼ã¿æåéçºã¯ãã²ã¼ã æ¥çã§å¤ãããææ話ããã¦ãããããã¯ã®ããã§ããç´ æ´ãããè³æã¨ãã¦ãFrostbyteããã®ã¹ã©ã¤ãã¸ã®ãªã³ã¯è²¼ã£ã¦ããã¾ãããhttps://www.ea.com/frostbite/news/introduction-to-data-oriented-design
ãFrostbyteããã®ã¹ã©ã¤ããè¦ãã¨æããããããããã¾ããããåçèªä½ã¯ç°¡åã§ãããã®ä»¶ã®å¤§ããªèª²é¡ã¯ãçµå±ã®ã¨ããã©ã®ããã«ç¾å®çãªéçºã¨ãã¦æç«ããããã ã¨æãã¾ãããã ã®é åã¨ãã¦ãã¹ã¦ãç¨æããã¨ããã§ã人éãéçºã«èããããªããã°æå³ã¯ããã¾ããã
ãã¼ã¿æåã®åºæ¬çãªèãæ¹
ããã¼ã¿æåã¯ãæçµçã«ã¯ä½ããã®è¨è¨ã§å©ç¨ããããã©ããããã¯ãã§ãããåãã«æ ¹å¹¹ã®åä½ç¹æ§ãããç解ãã¦å°éããå¿ è¦ãããã¾ããåé ã§ãªã³ã¯ããFrostbyteããã®ã¹ã©ã¤ããä¸å¯§ã«èª¬æããã¦ãã¾ãããä»æ¥ã§ã¯SIMDãå©ç¨ãããã¨ãåæã«ãªãã¯ããªã®ã§ããã®è¾ºãå ãã¤ã¤ãã¡ãã§ãåºæ¬çãªèãæ¹ã説æããã¾ãã
ãCPUã¯ããããã¼ã¿é åã¸ã®ååã¢ã¯ã»ã¹ãªã©ã§ãã£ãã·ã¥ãã¹ãèµ·ãã¦ãã¾ã£ãå ´åãç¶ãé åãå·»ãè¾¼ããããªå½¢ã§ããã£ãã·ã¥ã©ã¤ã³ã®ãµã¤ãºã§ã®åå¾ãè¡ãã¾ãã
ï¼ç¹ã«L1ãã£ãã·ã¥ã©ã¤ã³ã®ãµã¤ãºã¯ãC++17ãã
https://en.cppreference.com/w/cpp/thread/hardware_destructive_interference_sizeã
ã¨ãã¦åå¾ã§ãã¾ããï¼
ããã®å¾ã«ç¶ãã¦ã¡ã¢ãªçãªé£æ¥ãã¼ã¿ã¸ã®ã¢ã¯ã»ã¹ãè¡ãå ´åããã£ãã·ã¥ã©ã¤ã³ãæ´»ç¨ã§ããããé«éã«ãªããã¨ãæ³å®ããã¾ããL1ãã£ãã·ã¥ãã®ãã®ã¯é常ãã£ãã·ã¥ã©ã¤ã³ã®ãµã¤ãºããã大ããã®ã§ãã³ã¼ãã®ä¸ãæã§è¤æ°ã®é¢ããé åã«ã¢ã¯ã»ã¹ããå ´åããããè¤æ°ã®L1ãã£ãã·ã¥ã©ã¤ã³ãä¿æã§ãããã¨ãæå¾ ã§ãã¾ããã¤ã¾ããã²ã¼ã æå³ã®æ°å¤ããDeinterleaveãªå½¢ã§ç©çé ç½®ããã¦ããã°ããã¼ã¿æåçã«é½åãè¯ãã®ã§ããã
ãæ´ã«SIMDã®ã¬ã¸ã¹ã¿ã«å¯¾ãã¦ã®æä½ããå¤ã®Load/Storeãé£æ¥ããã¡ã¢ãªé åã«å¯¾ãã¦ã®è¡çºã«ãªãã¾ããDeinterleaveããã¦ããã°ãåæã«SIMDãæ´»ç¨ããããã¨ããäºã§ãã
ï¼åèï¼_mm256_load_psã_mm256_store_psï¼
ãã¾ãããããã®è©±ã¯ãã«ãã¹ã¬ããã§ã®æ´»ç¨ããã¾ããã¾ãããå½å ±æã«æ°ãä»ãããããã§ããããã
ãã¼ã¿æåéçºã®æå©ã§ãªãç¹
ãå è¿°ã®åºæ¬çãªèãæ¹ã§Demystifyããå½¢ã«ãªãã¾ãããããã¼ã¿æåéçºã¯éæ³ã§ã¯ãªãã®ã§ãããã§ãããæ°´å¹³æ¹åã®ããã¨ãã«ã¯ç¢ºå®ãªå©ç¹ã¯ããã¾ãããä¸å¾ã§çºçãã¦å çã«å®çµããå¦çã«ã¤ãã¦ã¯å¹æçãªã®ã§ããããã以å¤ã¯ããæ¹æ¬¡ç¬¬ã§ãããããã¦æ®éããã以ä¸ã ã¨ãããã¨ã§ããã
ãã¾ãã主観çãªè©ä¾¡ã§ãããè¨è¨çã«ãé£æ度ãé«ãã¨æãã¾ãã
ãDDDçã®ææ³ã«åºã¥ãããªãã¸ã§ã¯ãæåã§ã¯ãè¨èªä¸ã®ãã¯ã©ã¹ããã¡ã½ããããã¡ã³ããã¨ãã£ãè«ççãªã³ã³ã»ãããå©ç¨ãã¦è¨è¨çä¸ç観ãèªç±ã«æ§ç¯ããã¨æãã¾ããä¸æ¹ã§ãã¼ã¿æåéçºã§ã¯ããã¼ã¿ãã©ã®ããã«ä¸¦ãã§ãããã«ã¤ãã¦ã®ãã¼ãã¦ã§ã¢çå¶ç´ã大åæã¨ãã¦å ¥ãã¾ããããããã飲ã¿è¾¼ãã§ããã¾ãããªãã®ãè¨è¨ã®ä»äºã§ã¯ããã¾ãããå°ãä¸ç´ã ã¨ããããããããã¾ãã
ã¨ãããããã£ã¦ã¿ã
ããã¼ã¿æåéçºã®å®ç¾æ¹æ³ã¯ã±ã¼ã¹ãã¤ã±ã¼ã¹ã ã¨æãã¾ãããç¾å®çã«ä¸ä¾ã¨ãã¦ã©ãå®ç¾ããããã示ãã°ãããªãã«å½¹ã«ç«ã¤ã§ãããã¨ä¿¡ãããµã³ãã«ã³ã¼ããé©å½ã«è²¼ã£ã¦ãã¾ãã¾ãã
ãC++ã§ãããèªåã®åºç¤ã«ä¾åãã¦ãããããæ½è±¡çã«èªãã§ãã ããã
ãã³ã¡ã³ããè¦ãªãã追ã£ã¦é ããæ¹ãåãããããããããã¾ããããã¶ãã¯ãªã¨ããæµãã説æãã¾ãã
ãã¾ããã²ã¼ã å çãªæå³ã¨ãã¦ã®å¤ãããã¯ãã®æå³(ValueSemantics)ãå®ç¾©ãããããçµã¿åããã¦ã²ã¼ã å æ¦å¿µ(GameObject)ã®å½¢ãå®ç¾©ãã¾ãããã®æ¦å¿µã¯ProfileIdã§æå®ã§ãããã®ã«ãªãã¾ãã
ãProfileIdãå©ç¨ãã¦ãå®éã«GameObjectã®ã¤ã³ã¹ã¿ã³ã¹ãä½æãããã¨ãã§ããããã«ãªãã¾ããä¸ã¤ã®GameObjectã®ã¤ã³ã¹ã¿ã³ã¹ã¯ãValueSemanticsã§å®ç¾©ããå¤ãä¸ã¤æã¡ã¾ãããå é¨çãªé ç½®ã¨ãã¦ãã¼ã¿æåã«ãªãããã«ãé åã¨ãã¦é ç½®ããã¦ãã¾ããããããå¤å´ããã¯ãã®è©³ç´°ã¯è§¦ããã«æ¸ãããã«ãªã£ã¦ãã¾ãã
ãGameObjectã§ã²ã¼ã å ã®ãã£ã©ã¯ã¿ã¼ãç©ä½ã表ãã¦ãã²ã¼ã ã®å®è£ ãé²ãã¦ããããã§ããã
ãèå¿ã®ãã¼ã¿æåçãªä¸å¾å¦çï¼forçãªå¦çï¼ã¯ãããã§ã¯ExecuteJobSingleThreadedã¨ããå¦çã§å®è¡ããã¦ãã¾ããä»»æã®è¤æ°ã®Profileã«ã¤ãã¦ã®åãValueSemanticsã対象ã«ããå¦çãå®è¡ããããå³æå®äºã§ãªããã«ãã¹ã¬ããã§ã®ã¹ã±ã¸ã¥ã¼ã«ã«ããããã§ãã¾ãã
ãJobã®ä¸èº«ã¯ãç¬èªã®SIMDåºç¤ãå©ç¨ãã¦ä»¥ä¸ã«ç¤ºããããªå½¢ã§è¨è¿°ããã¦ããã¾ããå 容ã¯ãå ¨å¡ã®HPã«1ãã¡ã¼ã¸ãä¸ããã¨ããæå³ä¸æãªãã®ã§ãã
ãä¸å¿ã³ã¡ã³ããã¦ããã¾ãããè¨ç®ãå°ãªããã¦ãSIMDã«ããè¨ç®ã¯ãã®ç¨åº¦ã®ã±ã¼ã¹ã§ã¯ãã¾ãç´æ¥çã«é«éåã®å½¹ã«ã¯ç«ããªãã¨æãã¾ãããªãã¸ã§ã¯ãæåã«å¯¾ããé«éåãè¦ãããã¨ããã°ããã¼ã¿æåã«ãããã£ãã·ã¥ã©ã¤ã³ã®æ´»ç¨çã®æ¹åã«ãããã®ã«ãªãã§ãããã
ãããã¯ããã¨ãã¦SIMDåºç¤ã¯èªèº«ã®å½¹å²ãé©åã«é å¼µãããã«ãªã£ã¦ããã¾ãã¦ãã©ã³ã¿ã¤ã ã§AVX512f/AVX2/SSE4.1åºæºããé©åãªãã®ãé¸ã°ããããã«ã¯ãªã£ã¦ãã¾ããï¼ä¸ã®ç»åã§ã¯AVX2ãé¸æããã¦ããï¼
ãSIMDã®ç«¯æ°ããã£ã³ã°ãã¼ãã³ã¹ãã§æé»çã«å¯¾å¿ããã¾ããï¼ãã¼ã¿æååºç¤ã®ã¢ãã±ã¼ã·ã§ã³ç®¡çå´ã«å·¥å¤«ãå
¥ã£ã¦ããããï¼
ãã¾ããæå¾ã®æ¹ã«ãOOPCharacterHpDrawerãã¨ãã輩ãããã¾ããããªãã¸ã§ã¯ãæåã¨ä¸¡ç«ãã§ããã¨ããäºã§ããããã§ã¯æ§ãã¦ããGameObjectIdã®é åã®0çªç®ã«ãããã£ã©ã¯ã¿ã¼ã«ã¤ãã¦ãHPãã³ã³ã½ã¼ã«ã«è¡¨ç¤ºãã¦ã¾ãã
ãæ°´å¹³æ¹åã®é¢ä¿ãé¸æçãªå¦çã¯ãé©å®OOPã«åãæ¿ããæ¹ãè¯ãã§ãããã
ããã©ã¼ãã³ã¹
ããã§ã¢ãªæ¯è¼ã¯é£ããã§ããéãç´ã£ã¦çæ³çãªä¸å¾å¦çã®å·®ã ããéãªæ¸¬å®ã§ç¤ºãã¾ããæ£å½æ§ã¯ï¼ã¨ãã¦è¦ã¦ãã ããããªãã¸ã§ã¯ãæåã¨ãã¦ã®ç価ãªå¦çã¨ãã¦ä»¥ä¸ã®ãããªãã®ãå®ç¾©ãã¾ãã
ããªãã¸ã§ã¯ãã¯C#ã§ããåç §åçã³ã³ã»ããã§ç¨æãããã®ãä¸è¬çã§ãããããããã¤ã³ã¿ãä»ããéæ¥ã¢ã¯ã»ã¹ã¨ãã¦ããã¾ãã
ããã¡ãã®ãã¼ã¿æåä¸å¾å¦çã®åºéã¨æ¯è¼ãã¦ã¿ã¾ãããã15000åã®Characterã«ã¤ãã¦1ãã¡ã¼ã¸ä¸ããå¦çãè¡ãã¾ãããã¦ãçµæã¯â¦â¦
ãã ããããããªæãã«ãªãã¾ãããï¼Releaseãæ大æé©åãstd::chrono::system_clock::now()ã§è¨æ¸¬ã[email protected], DDR5 4800 mt/s)
ãè¡ã£ã¦ãããã¨ããå·®ã®çç±ã¯ããããæããã ã¨æãã¾ãããªãã¸ã§ã¯ãæåå´ãé ãã®ã¯ããã¤ã³ã¿ã¢ã¯ã»ã¹ã«ãªã£ã¦ãããã¨ã¨ããã£ãã·ã¥ã©ã¤ã³ãå¹çããæ´»ç¨ãããªãäºã主ã§ããããå ã»ã©ãå°ã触ãã¾ããããè¨ç®èªä½ã¯å°ãªããããã·ã³ã°ã«ã¹ã¬ããã¨ã¯ãããã®å ´åã§ã¯SIMDãå·®ãçãã§ãããã¯ãã±ã£ã¨è¦ã§ã¯åããã¾ããã
ãããã°ãæ¸ãã¦ããéã«æ°ã¥ããã®ã§ãããèªåã®ã¢ãã±ã¼ã¿ã®ä»çµã¿ä¸ããªãã¸ã§ã¯ãæåå´ãè¿ãä½ç½®ã«å ¨å¡é£ç¶ãã¦é ç½®ããã¦ãããããªæ°ã¯ãã¾ããããç¾å®çãªé ç½®ã ã¨ãããå°ãå·®ãã¤ãããããã¾ããã
ãããã«
ããã¼ã¿æåã¯å¶ç´ãå¼·ãããã¾ãæç«ãããè¨è¨ã¯ããããããªãå°è±¡ã§ãã
ãããããã°ãæè¿æµè¡ãã®ãã¼ã¿æåè¨è¨ã«ãECSãã¨ããèãæ¹ãããããã§ããããããã©ã®ãããªãã®ã§ãããã¼ã¿æåã®å©ç¨ã¯ãå人çã«ã¯(å°ãªãã¨ããã¼ã éçºã§ã¯)ãã¾ããå§ããã¾ãããåçããæ°´å¹³æ¹åã®é¢ä¿ã¯å¼±ããæå©ãªç¶æ³ãéå®çã§ããã¾ããé«éåã®è¦³ç¹ã§ããä¾ãã°D3D12çã®ç¬èªæ´»ç¨ã§GPUå´ãåæã«æé©åã§ãã¦ããªããã°ãGPU boundã«ãªã£ã¦ãã¾ãã»ã¨ãã©æå³ããªã訳ã§ããããã«è¨è¿°èªä½ããèªç¶ã ã¨ã¯è¨ããªãã¨å人çã«ã¯æãã¾ããå ¨ä½çã«ãã¼ã ã®ç·´åº¦ãå¿ è¦ã«ãªããããã§ãããã
ãããã§ããæéãç®æããã¿ã¼ã³ã®ä¸ã¤ãç解ãã¦ãããã¨ã¯ãéçºè ã¨ãã¦ã¯ç¡é§ã«ãªããã¨ã¯ç¡ãã¯ãã§ãã
â ã¤ã³ãã£ãããã«ã¼ãã§ã¯3Dã²ã¼ã éçºã«ãåãçµãã§ããã¾ããèå³ãããæ¹ã¯æ¯éæ¡ç¨æ å ±ãã確èªãã ãããâ