ããã¯ããªãŒããã°ã©ãã³ã°ã®åºç€ãšã¢ãããã¯æäœã«çŠç¹ãåœãŠãŠè§£èª¬ã髿§èœãªäžŠè¡ã·ã¹ãã ã«ãããéèŠæ§ããäžççãªäºäŸãšå®è·µçãªæŽå¯ã亀ããŠç޹ä»ããŸãã
ããã¯ããªãŒããã°ã©ãã³ã°ãè§£ãæããïŒã°ããŒãã«éçºè ã®ããã®ã¢ãããã¯æäœã®å
仿¥ã®çžäºæ¥ç¶ãããããžã¿ã«ç°å¢ã«ãããŠãããã©ãŒãã³ã¹ãšã¹ã±ãŒã©ããªãã£ã¯æéèŠã§ããã¢ããªã±ãŒã·ã§ã³ãå¢å ããè² è·ãè€éãªèšç®ãåŠçããããã«é²åããã«ã€ããŠããã¥ãŒããã¯ã¹ãã»ããã©ã®ãããªåŸæ¥ã®åæã¡ã«ããºã ã¯ããã«ããã¯ã«ãªãå¯èœæ§ããããŸããããã§ããã¯ããªãŒããã°ã©ãã³ã°ã匷åãªãã©ãã€ã ãšããŠç»å Žããéåžžã«å¹ççã§å¿çæ§ã®é«ã䞊è¡ã·ã¹ãã ãžã®éãæäŸããŸããããã¯ããªãŒããã°ã©ãã³ã°ã®äžå¿ã«ã¯ãã¢ãããã¯æäœãšããåºæ¬çãªæŠå¿µããããŸãããã®å æ¬çãªã¬ã€ãã§ã¯ãããã¯ããªãŒããã°ã©ãã³ã°ãšãäžçäžã®éçºè ã«ãšã£ãŠã®ã¢ãããã¯æäœã®éèŠãªåœ¹å²ãè§£ãæãããŸãã
ããã¯ããªãŒããã°ã©ãã³ã°ãšã¯ïŒ
ããã¯ããªãŒããã°ã©ãã³ã°ã¯ãã·ã¹ãã å šäœã®åé²ãä¿èšŒããäžŠè¡æ§å¶åŸ¡æŠç¥ã§ããããã¯ããªãŒã·ã¹ãã ã§ã¯ãä»ã®ã¹ã¬ãããé å»¶ãŸãã¯äžæããããšããŠããå°ãªããšã1ã€ã®ã¹ã¬ããã¯åžžã«åé²ããŸããããã¯ãããã¯ããŒã¹ã®ã·ã¹ãã ãšã¯å¯Ÿç §çã§ããããã¯ããŒã¹ã®ã·ã¹ãã ã§ã¯ãããã¯ãä¿æããŠããã¹ã¬ãããäžæããããšããã®ããã¯ãå¿ èŠãšããä»ã®ã¹ã¬ãããé²è¡ã§ããªããªãå¯èœæ§ããããŸããããã¯ãããããã¯ãã©ã€ãããã¯ã«ã€ãªãããã¢ããªã±ãŒã·ã§ã³ã®å¿çæ§ã«æ·±å»ãªåœ±é¿ãäžããããšããããŸãã
ããã¯ããªãŒããã°ã©ãã³ã°ã®äž»ãªç®æšã¯ãåŸæ¥ã®ããã¯ã¡ã«ããºã ã«é¢é£ããç«¶åãæœåšçãªããããã³ã°ãåé¿ããããšã§ããæç€ºçãªããã¯ãªãã§å ±æããŒã¿ãæäœããã¢ã«ãŽãªãºã ãæ éã«èšèšããããšã§ãéçºè ã¯ä»¥äžãå®çŸã§ããŸãïŒ
- ããã©ãŒãã³ã¹ã®åäžïŒç¹ã«é«ãç«¶åäžã§ãããã¯ã®ååŸãšè§£æŸã«äŒŽããªãŒããŒããããåæžããŸãã
- ã¹ã±ãŒã©ããªãã£ã®åŒ·åïŒã¹ã¬ãããäºãããããã¯ããå¯èœæ§ãäœããªãããããã«ãã³ã¢ããã»ããµäžã§ã·ã¹ãã ããã广çã«ã¹ã±ãŒã«ããŸãã
- èé害æ§ã®åäžïŒãããããã¯ãåªå é äœã®é転ãªã©ãããã¯ããŒã¹ã®ã·ã¹ãã ã麻çºãããå¯èœæ§ã®ããåé¡ãåé¿ããŸãã
ç€ç³ïŒã¢ãããã¯æäœ
ã¢ãããã¯æäœã¯ãããã¯ããªãŒããã°ã©ãã³ã°ãæ§ç¯ãããåºç€ã§ããã¢ãããã¯æäœãšã¯ãäžæãããããšãªãå®å šã«å®è¡ããããããããã¯å šãå®è¡ãããªãããšãä¿èšŒãããæäœã§ããä»ã®ã¹ã¬ããããèŠããšãã¢ãããã¯æäœã¯ç¬æã«çºçããããã«èŠããŸãããã®äžå¯åæ§ã¯ãè€æ°ã®ã¹ã¬ãããå ±æããŒã¿ã«åæã«ã¢ã¯ã»ã¹ã倿Žããéã«ãããŒã¿ã®äžè²«æ§ãç¶æããããã«äžå¯æ¬ ã§ãã
次ã®ããã«èããŠã¿ãŠãã ããïŒã¡ã¢ãªã«æ°å€ãæžã蟌ãå Žåãã¢ãããã¯ãªæžã蟌ã¿ã¯æ°å€å šäœãæžã蟌ãŸããããšãä¿èšŒããŸããéã¢ãããã¯ãªæžã蟌ã¿ã¯éäžã§äžæãããå¯èœæ§ããããéšåçã«æžã蟌ãŸããç Žæããå€ãä»ã®ã¹ã¬ãããèªã¿åãå¯èœæ§ããããŸããã¢ãããã¯æäœã¯ããã®ãããªç«¶åç¶æ ãéåžžã«äœãã¬ãã«ã§é²ããŸãã
äžè¬çãªã¢ãããã¯æäœ
ã¢ãããã¯æäœã®å ·äœçãªã»ããã¯ããŒããŠã§ã¢ã¢ãŒããã¯ãã£ãããã°ã©ãã³ã°èšèªã«ãã£ãŠç°ãªããŸãããããã€ãã®åºæ¬çãªæäœã¯åºããµããŒããããŠããŸãïŒ
- ã¢ãããã¯èªã¿åãïŒã¡ã¢ãªããå€ãåäžã®ãäžæäžå¯èœãªæäœãšããŠèªã¿åããŸãã
- ã¢ãããã¯æžã蟌ã¿ïŒã¡ã¢ãªã«å€ãåäžã®ãäžæäžå¯èœãªæäœãšããŠæžã蟌ã¿ãŸãã
- ãã§ããã»ã¢ã³ãã»ã¢ãã (FAA)ïŒã¡ã¢ãªäœçœ®ããå€ãã¢ãããã¯ã«èªã¿åããæå®ãããéãå ç®ããæ°ããå€ãæžãæ»ããŸããå ã®å€ãè¿ããŸããããã¯ã¢ãããã¯ãªã«ãŠã³ã¿ãäœæããã®ã«éåžžã«äŸ¿å©ã§ãã
- ã³ã³ãã¢ã»ã¢ã³ãã»ã¹ã¯ãã (CAS)ïŒããã¯ããããããã¯ããªãŒããã°ã©ãã³ã°ã«ãšã£ãŠæãéèŠãªã¢ãããã¯ããªããã£ãã§ããCASã¯3ã€ã®åŒæ°ãåããŸãïŒã¡ã¢ãªã¢ãã¬ã¹ãæåŸ ãããå€ãå€ããããŠæ°ããå€ã§ããã¡ã¢ãªã¢ãã¬ã¹ã®å€ãæåŸ ãããå€ãå€ãšçããããã¢ãããã¯ã«ãã§ãã¯ããŸããçããå Žåãã¡ã¢ãªã¢ãã¬ã¹ãæ°ããå€ã§æŽæ°ããtrueïŒãŸãã¯å€ãå€ïŒãè¿ããŸããå€ãæåŸ ãããå€ãå€ãšäžèŽããªãå Žåãäœãããã«falseïŒãŸãã¯çŸåšã®å€ïŒãè¿ããŸãã
- ãã§ããã»ã¢ã³ãã»ãªã¢ããã§ããã»ã¢ã³ãã»ã¢ã³ãããã§ããã»ã¢ã³ãã»XORïŒFAAãšåæ§ã«ããããã®æäœã¯ã¡ã¢ãªã¢ãã¬ã¹ã®çŸåšã®å€ãšäžããããå€ãšã®éã§ãããåäœã®æŒç®ïŒORãANDãXORïŒãå®è¡ãããã®çµæãæžãæ»ããŸãã
ãªãã¢ãããã¯æäœã¯ããã¯ããªãŒã«äžå¯æ¬ ãªã®ãïŒ
ããã¯ããªãŒã¢ã«ãŽãªãºã ã¯ãåŸæ¥ã®ããã¯ãªãã§å ±æããŒã¿ãå®å šã«æäœããããã«ã¢ãããã¯æäœã«äŸåããŠããŸããç¹ã«ã³ã³ãã¢ã»ã¢ã³ãã»ã¹ã¯ããïŒCASïŒæäœã¯éèŠã§ããè€æ°ã®ã¹ã¬ãããå ±æã«ãŠã³ã¿ãæŽæ°ããå¿ èŠãããã·ããªãªãèããŠã¿ãŸããããåçŽãªã¢ãããŒãã§ã¯ãã«ãŠã³ã¿ãèªã¿åããã€ã³ã¯ãªã¡ã³ãããæžãæ»ããšããæé ã«ãªããŸããããã®ã·ãŒã±ã³ã¹ã¯ç«¶åç¶æ ã«é¥ããããã§ãïŒ
// éã¢ãããã¯ãªã€ã³ã¯ãªã¡ã³ãïŒç«¶åç¶æ ã«èåŒ±ïŒ int counter = shared_variable; counter++; shared_variable = counter;
ããã¹ã¬ããAãå€5ãèªã¿åãã6ãæžãæ»ãåã«ã¹ã¬ããBã5ãèªã¿åããããã6ã«ã€ã³ã¯ãªã¡ã³ãããŠ6ãæžãæ»ããå Žåããã®åŸã¹ã¬ããAã6ãæžãæ»ããã¹ã¬ããBã®æŽæ°ãäžæžãããŠããŸããŸããã«ãŠã³ã¿ã¯7ã«ãªãã¹ãã§ããã6ã«ãããªããŸããã
CASã䜿çšãããšãæäœã¯æ¬¡ã®ããã«ãªããŸãïŒ
// CASã䜿çšããã¢ãããã¯ãªã€ã³ã¯ãªã¡ã³ã
int expected_value = shared_variable.load();
int new_value;
do {
new_value = expected_value + 1;
} while (!shared_variable.compare_exchange_weak(expected_value, new_value));
ãã®CASããŒã¹ã®ã¢ãããŒãã§ã¯ïŒ
- ã¹ã¬ããã¯çŸåšã®å€ïŒ`expected_value`ïŒãèªã¿åããŸãã
- `new_value`ãèšç®ããŸãã
- `shared_variable`ã®å€ããŸã `expected_value`ã§ããå Žåã«éãã`expected_value`ã`new_value`ã§ã¹ã¯ããããããšè©Šã¿ãŸãã
- ã¹ã¯ãããæåããã°ãæäœã¯å®äºã§ãã
- ã¹ã¯ããã倱æããå ŽåïŒãã®éã«å¥ã®ã¹ã¬ããã`shared_variable`ã倿ŽããããïŒã`expected_value`ã¯`shared_variable`ã®çŸåšã®å€ã§æŽæ°ãããã«ãŒãã¯CASæäœãå詊è¡ããŸãã
ãã®å詊è¡ã«ãŒãã«ãããã€ã³ã¯ãªã¡ã³ãæäœãæçµçã«æåããããšãä¿èšŒãããããã¯ãªãã§åé²ãä¿èšŒãããŸããïŒC++ã§äžè¬çãªïŒ`compare_exchange_weak`ã®äœ¿çšã¯ãåäžã®æäœå ã§ãã§ãã¯ãè€æ°åå®è¡ããå¯èœæ§ããããŸãããäžéšã®ã¢ãŒããã¯ãã£ã§ã¯ããå¹ççã§ããåäžã®ãã¹ã§çµ¶å¯Ÿçãªç¢ºå®æ§ãæ±ããå Žåã¯ã`compare_exchange_strong`ã䜿çšãããŸãã
ããã¯ããªãŒã®ç¹æ§ãéæãã
çã«ããã¯ããªãŒãšèŠãªãããããã«ã¯ãã¢ã«ãŽãªãºã ã¯æ¬¡ã®æ¡ä»¶ãæºããå¿ èŠããããŸãïŒ
- ã·ã¹ãã å šäœã®é²æã®ä¿èšŒïŒãããªãå®è¡ã«ãããŠããå°ãªããšã1ã€ã®ã¹ã¬ãããæéã®ã¹ãããæ°ã§ãã®æäœãå®äºããŸããããã¯ãäžéšã®ã¹ã¬ããã飢é€ç¶æ ã«é¥ã£ããé å»¶ãããããŠããã·ã¹ãã å šäœãšããŠã¯é²æãç¶ããããšãæå³ããŸãã
ããã«åŒ·åãªãŠã§ã€ãããªãŒããã°ã©ãã³ã°ãšããé¢é£æŠå¿µããããŸãããŠã§ã€ãããªãŒã¢ã«ãŽãªãºã ã¯ãä»ã®ã¹ã¬ããã®ç¶æ ã«é¢ä¿ãªãããã¹ãŠã®ã¹ã¬ãããæéã®ã¹ãããæ°ã§ãã®æäœãå®äºããããšãä¿èšŒããŸããçæ³çã§ã¯ãããŸããããŠã§ã€ãããªãŒã¢ã«ãŽãªãºã ã¯èšèšãšå®è£ ãèããè€éã«ãªãããšããããããŸãã
ããã¯ããªãŒããã°ã©ãã³ã°ã«ããã課é¡
ãã®å©ç¹ã¯å€§ãããã®ã®ãããã¯ããªãŒããã°ã©ãã³ã°ã¯äžèœè¬ã§ã¯ãªããç¬èªã®äžé£ã®èª²é¡ã䌎ããŸãïŒ
1. è€éããšæ£ç¢ºæ§
æ£ããããã¯ããªãŒã¢ã«ãŽãªãºã ãèšèšããããšã¯éåžžã«é£ããããšã§ç¥ãããŠããŸããã¡ã¢ãªã¢ãã«ãã¢ãããã¯æäœããããŠçµéšè±å¯ãªéçºè ã§ããèŠèœãšãå¯èœæ§ã®ãã埮åŠãªç«¶åç¶æ ã«ã€ããŠã®æ·±ãçè§£ãå¿ èŠã§ããããã¯ããªãŒã³ãŒãã®æ£ããã蚌æããã«ã¯ããã°ãã°åœ¢åŒææ³ãå³å¯ãªãã¹ããå¿ èŠãšãªããŸãã
2. ABAåé¡
ABAåé¡ã¯ãç¹ã«CASã䜿çšããããã¯ããªãŒããŒã¿æ§é ã«ãããå€å žçãªèª²é¡ã§ããããã¯ãããå€ãèªã¿åããïŒAïŒããã®åŸå¥ã®ã¹ã¬ããã«ãã£ãŠBã«å€æŽãããæåã®ã¹ã¬ãããCASæäœãå®è¡ããåã«åã³Aã«æ»ãããå Žåã«çºçããŸããå€ãAã§ããããCASæäœã¯æåããŸãããæåã®èªã¿åããšCASã®éã«ããŒã¿ãå€§å¹ ã«å€æŽãããå¯èœæ§ããããäžæ£ç¢ºãªåäœã«ã€ãªãããŸãã
äŸïŒ
- ã¹ã¬ãã1ãå ±æå€æ°ããå€Aãèªã¿åããŸãã
- ã¹ã¬ãã2ãå€ãBã«å€æŽããŸãã
- ã¹ã¬ãã2ãå€ãAã«æ»ããŸãã
- ã¹ã¬ãã1ãå ã®å€Aã§CASã詊ã¿ãŸããå€ããŸã Aã§ããããCASã¯æåããŸãããã¹ã¬ãã1ãèªèããŠããªãã¹ã¬ãã2ã«ããä»åšãã倿Žããæäœã®åæãç¡å¹ã«ããå¯èœæ§ããããŸãã
ABAåé¡ã®è§£æ±ºçã«ã¯ãéåžžãã¿ã°ä»ããã€ã³ã¿ãããŒãžã§ã³ã«ãŠã³ã¿ã®äœ¿çšãå«ãŸããŸããã¿ã°ä»ããã€ã³ã¿ã¯ããã€ã³ã¿ã«ããŒãžã§ã³çªå·ïŒã¿ã°ïŒãé¢é£ä»ããŸãã倿Žã®ãã³ã«ã¿ã°ãã€ã³ã¯ãªã¡ã³ããããŸããCASæäœã¯ãã€ã³ã¿ãšã¿ã°ã®äž¡æ¹ããã§ãã¯ãããããABAåé¡ãçºçããã®ãã¯ããã«å°é£ã«ããŸãã
3. ã¡ã¢ãªç®¡ç
C++ã®ãããªèšèªã§ã¯ãããã¯ããªãŒæ§é ã«ãããæåã®ã¡ã¢ãªç®¡çã¯ãããªãè€éãããããããŸããããã¯ããªãŒé£çµãªã¹ãå ã®ããŒããè«ççã«åé€ãããŠããä»ã®ã¹ã¬ããããŸã ãããæäœããŠããå¯èœæ§ãããããïŒè«ççã«åé€ãããåã«ãã®ãã€ã³ã¿ãèªã¿åã£ãå¯èœæ§ãããããïŒãããã«è§£æŸããããšã¯ã§ããŸãããããã«ã¯ã以äžã®ãããªé«åºŠãªã¡ã¢ãªè§£æŸæè¡ãå¿ èŠã§ãïŒ
- ãšããã¯ããŒã¹è§£æŸ (EBR)ïŒã¹ã¬ããã¯ãšããã¯å ã§æäœããŸããã¡ã¢ãªã¯ããã¹ãŠã®ã¹ã¬ãããç¹å®ã®ãšããã¯ãééããåŸã«ã®ã¿è§£æŸãããŸãã
- ãã¶ãŒããã€ã³ã¿ïŒã¹ã¬ããã¯çŸåšã¢ã¯ã»ã¹ããŠãããã€ã³ã¿ãç»é²ããŸããã¡ã¢ãªã¯ãã©ã®ã¹ã¬ãããããã«ãã¶ãŒããã€ã³ã¿ãæã£ãŠããªãå Žåã«ã®ã¿è§£æŸã§ããŸãã
- åç §ã«ãŠã³ã¿ïŒäžèŠåçŽã«èŠããŸãããããã¯ããªãŒãªæ¹æ³ã§ã¢ãããã¯ãªåç §ã«ãŠã³ã¿ãå®è£ ããããšèªäœãè€éã§ãããããã©ãŒãã³ã¹ã«åœ±é¿ãäžããå¯èœæ§ããããŸãã
ã¬ããŒãžã³ã¬ã¯ã·ã§ã³ãæã€ãããŒãžãèšèªïŒJavaãC#ãªã©ïŒã¯ã¡ã¢ãªç®¡çãç°¡çŽ åã§ããŸãããGCã®äžæåæ¢ãšãã®ããã¯ããªãŒä¿èšŒãžã®åœ±é¿ã«é¢ããŠãç¬èªã®è€éããæã¡èŸŒã¿ãŸãã
4. ããã©ãŒãã³ã¹ã®äºæž¬å¯èœæ§
ããã¯ããªãŒã¯å¹³åçãªããã©ãŒãã³ã¹ãåäžãããããšãã§ããŸãããCASã«ãŒãã§ã®å詊è¡ã«ãããåã ã®æäœã«ã¯ããé·ãæéããããå ŽåããããŸããããã«ãããããã¯ã®æå€§åŸ æ©æéããã°ãã°å¶éãããŠããïŒãã ããããããã¯ã®å Žåã¯ç¡éã«ãªãå¯èœæ§ãããïŒããã¯ããŒã¹ã®ã¢ãããŒããšæ¯èŒããŠãããã©ãŒãã³ã¹ã®äºæž¬ãé£ãããªãããšããããŸãã
5. ãããã°ãšããŒã«
ããã¯ããªãŒã³ãŒãã®ãããã°ã¯èããå°é£ã§ããæšæºçãªãããã°ããŒã«ã¯ãã¢ãããã¯æäœäžã®ã·ã¹ãã ã®ç¶æ ãæ£ç¢ºã«åæ ããªãå¯èœæ§ããããå®è¡ãããŒãèŠèŠåããããšãå°é£ã§ãã
ããã¯ããªãŒããã°ã©ãã³ã°ã¯ã©ãã§äœ¿ããããïŒ
ç¹å®ã®ãã¡ã€ã³ã®èŠæ±ã®å³ããããã©ãŒãã³ã¹ãšã¹ã±ãŒã©ããªãã£èŠä»¶ã«ãããããã¯ããªãŒããã°ã©ãã³ã°ã¯äžå¯æ¬ ãªããŒã«ãšãªã£ãŠããŸããäžçäžã®äºäŸãè±å¯ã«ãããŸãïŒ
- é«é »åºŠååŒ (HFT)ïŒããªç§ãéèŠãªéèåžå Žã§ã¯ãæå°éã®ã¬ã€ãã³ã·ã§æ³šææ¿ãååŒå®è¡ããªã¹ã¯èšç®ã管çããããã«ããã¯ããªãŒããŒã¿æ§é ã䜿çšãããŸãããã³ãã³ããã¥ãŒãšãŒã¯ãæ±äº¬ã®ååŒæã®ã·ã¹ãã ã¯ã極端ãªé床ã§èšå€§ãªæ°ã®ãã©ã³ã¶ã¯ã·ã§ã³ãåŠçããããã«ããã®ãããªæè¡ã«äŸåããŠããŸãã
- ãªãã¬ãŒãã£ã³ã°ã·ã¹ãã ã®ã«ãŒãã«ïŒçŸä»£ã®ãªãã¬ãŒãã£ã³ã°ã·ã¹ãã ïŒLinuxãWindowsãmacOSãªã©ïŒã¯ãã¹ã±ãžã¥ãŒãªã³ã°ãã¥ãŒãå²ã蟌ã¿åŠçãããã»ã¹ééä¿¡ãªã©ã®éèŠãªã«ãŒãã«ããŒã¿æ§é ã«ããã¯ããªãŒæè¡ã䜿çšããé«è² è·äžã§ã®å¿çæ§ãç¶æããŠããŸãã
- ããŒã¿ããŒã¹ã·ã¹ãã ïŒé«æ§èœããŒã¿ããŒã¹ã¯ãå éšãã£ãã·ã¥ããã©ã³ã¶ã¯ã·ã§ã³ç®¡çãã€ã³ããã¯ã¹äœæã«ããã¯ããªãŒæ§é ããã°ãã°æ¡çšããé«éãªèªã¿æžãæäœãä¿èšŒããã°ããŒãã«ãªãŠãŒã¶ãŒããŒã¹ããµããŒãããŠããŸãã
- ã²ãŒã ãšã³ãžã³ïŒè€éãªã²ãŒã ã¯ãŒã«ãïŒãã°ãã°äžçäžã®ãã·ã³ã§å®è¡ãããïŒã«ãããè€æ°ã®ã¹ã¬ããéã§ã®ã²ãŒã ã®ç¶æ ãç©çæŒç®ãAIã®ãªã¢ã«ã¿ã€ã åæã¯ãããã¯ããªãŒã¢ãããŒãã®æ©æµãåããŸãã
- ãããã¯ãŒã¯æ©åšïŒã«ãŒã¿ãŒããã¡ã€ã¢ãŠã©ãŒã«ãé«éãããã¯ãŒã¯ã¹ã€ããã¯ããããã¯ãŒã¯ãã±ãããããããããããšãªãå¹ççã«åŠçããããã«ãããã¯ããªãŒãã¥ãŒããããã¡ããã°ãã°äœ¿çšããŸããããã¯ã°ããŒãã«ãªã€ã³ã¿ãŒãããã€ã³ãã©ã«ãšã£ãŠäžå¯æ¬ ã§ãã
- ç§åŠã·ãã¥ã¬ãŒã·ã§ã³ïŒæ°è±¡äºå ±ãåååååŠã倩äœç©çåŠã¢ããªã³ã°ãªã©ã®åéã«ãããå€§èŠæš¡ãªäžŠåã·ãã¥ã¬ãŒã·ã§ã³ã¯ãäœåãã®ããã»ããµã³ã¢ã«ãŸãããå ±æããŒã¿ã管çããããã«ããã¯ããªãŒããŒã¿æ§é ãæŽ»çšããŸãã
ããã¯ããªãŒæ§é ã®å®è£ ïŒå®è·µçãªäŸïŒæŠå¿µïŒ
CASã䜿çšããŠå®è£ ãããåçŽãªããã¯ããªãŒã¹ã¿ãã¯ãèããŠã¿ãŸããããã¹ã¿ãã¯ã«ã¯éåžžã`push`ã`pop`ã®ãããªæäœããããŸãã
ããŒã¿æ§é ïŒ
struct Node {
Value data;
Node* next;
};
class LockFreeStack {
private:
std::atomic head;
public:
void push(Value val) {
Node* newNode = new Node{val, nullptr};
Node* oldHead;
do {
oldHead = head.load(); // çŸåšã®headãã¢ãããã¯ã«èªã¿èŸŒã
newNode->next = oldHead;
// headã倿ŽãããŠããªããã°ãæ°ããheadãã¢ãããã¯ã«èšå®ããããšãã
} while (!head.compare_exchange_weak(oldHead, newNode));
}
Value pop() {
Node* oldHead;
Value val;
do {
oldHead = head.load(); // çŸåšã®headãã¢ãããã¯ã«èªã¿èŸŒã
if (!oldHead) {
// ã¹ã¿ãã¯ã空ãªã®ã§ãé©åã«åŠçããïŒäŸïŒäŸå€ãã¹ããŒããããçªå
µå€ãè¿ãïŒ
throw std::runtime_error("Stack underflow");
}
// çŸåšã®headãæ¬¡ã®ããŒãã®ãã€ã³ã¿ãšã¹ã¯ããããããšãã
// æåããå ŽåãoldHeadã¯popãããããŒããæã
} while (!head.compare_exchange_weak(oldHead, oldHead->next));
val = oldHead->data;
// åé¡ïŒABAåé¡ãuse-after-freeãªãã§oldHeadãå®å
šã«åé€ããã«ã¯ã©ãããã°ãããïŒ
// ããã§é«åºŠãªã¡ã¢ãªè§£æŸæè¡ãå¿
èŠã«ãªãã
// ãã¢ã³ã¹ãã¬ãŒã·ã§ã³ã®ãããå®å
šãªåé€ã¯çç¥ããã
// delete oldHead; // å®éã®ãã«ãã¹ã¬ããã·ããªãªã§ã¯å®å
šã§ã¯ãããŸããïŒ
return val;
}
};
`push`æäœã§ã¯ïŒ
- æ°ãã`Node`ãäœæãããŸãã
- çŸåšã®`head`ãã¢ãããã¯ã«èªã¿åãããŸãã
- æ°ããããŒãã®`next`ãã€ã³ã¿ã`oldHead`ã«èšå®ãããŸãã
- CASæäœã`head`ã`newNode`ãæãããã«æŽæ°ããããšããŸãã`load`ãš`compare_exchange_weak`ã®åŒã³åºãã®éã«`head`ãå¥ã®ã¹ã¬ããã«ãã£ãŠå€æŽãããå ŽåãCASã¯å€±æããã«ãŒãã¯å詊è¡ããŸãã
`pop`æäœã§ã¯ïŒ
- çŸåšã®`head`ãã¢ãããã¯ã«èªã¿åãããŸãã
- ã¹ã¿ãã¯ã空ã®å ŽåïŒ`oldHead`ãnullïŒããšã©ãŒãéç¥ãããŸãã
- CASæäœã`head`ã`oldHead->next`ãæãããã«æŽæ°ããããšããŸãã`head`ãå¥ã®ã¹ã¬ããã«ãã£ãŠå€æŽãããå ŽåãCASã¯å€±æããã«ãŒãã¯å詊è¡ããŸãã
- CASãæåãããšã`oldHead`ã¯ã¹ã¿ãã¯ããåé€ãããã°ããã®ããŒããæãããã«ãªããŸãããã®ããŒã¿ãååŸãããŸãã
ããã§éèŠãªæ¬ èœéšåã¯ã`oldHead`ã®å®å šãªè§£æŸã§ããåè¿°ã®éããããã¯æåã¡ã¢ãªç®¡çã®ããã¯ããªãŒæ§é ã«ããã倧ããªèª²é¡ã§ããuse-after-freeãšã©ãŒãé²ãããã«ããã¶ãŒããã€ã³ã¿ããšããã¯ããŒã¹è§£æŸã®ãããªé«åºŠãªã¡ã¢ãªç®¡çæè¡ãå¿ èŠãšããŸãã
æ£ããã¢ãããŒãã®éžæïŒãã㯠vs. ããã¯ããªãŒ
ããã¯ããªãŒããã°ã©ãã³ã°ã䜿çšããæ±ºå®ã¯ãã¢ããªã±ãŒã·ã§ã³ã®èŠä»¶ãæ éã«åæããäžã§è¡ãã¹ãã§ãïŒ
- äœç«¶åïŒã¹ã¬ããã®ç«¶åãéåžžã«äœãã·ããªãªã§ã¯ãåŸæ¥ã®ããã¯ã®æ¹ãå®è£ ããããã°ãç°¡åã§ããã®ãªãŒããŒãããã¯ç¡èŠã§ãããããããŸããã
- é«ç«¶åãšã¬ã€ãã³ã·ã®æåºŠïŒã¢ããªã±ãŒã·ã§ã³ãé«ãç«¶åãçµéšããäºæž¬å¯èœãªäœã¬ã€ãã³ã·ãå¿ èŠãšããå Žåãããã¯ããªãŒããã°ã©ãã³ã°ã¯å€§ããªå©ç¹ãæäŸã§ããŸãã
- ã·ã¹ãã å šäœã®é²æä¿èšŒïŒããã¯ç«¶åã«ããã·ã¹ãã ã®åæ¢ïŒãããããã¯ãåªå é äœã®é転ïŒãé¿ããããšãéèŠãªå Žåãããã¯ããªãŒã¯åŒ·åãªåè£ã§ãã
- éçºå·¥æ°ïŒããã¯ããªãŒã¢ã«ãŽãªãºã ã¯èããè€éã§ããå©çšå¯èœãªå°éç¥èãšéçºæéãè©äŸ¡ããŠãã ããã
ããã¯ããªãŒéçºã®ããã®ãã¹ããã©ã¯ãã£ã¹
ããã¯ããªãŒããã°ã©ãã³ã°ã«ææŠããéçºè ã¯ã以äžã®ãã¹ããã©ã¯ãã£ã¹ãèæ ®ããŠãã ããïŒ
- 匷åãªããªããã£ãããå§ããïŒèšèªãããŒããŠã§ã¢ãæäŸããã¢ãããã¯æäœïŒäŸïŒC++ã®`std::atomic`ãJavaã®`java.util.concurrent.atomic`ïŒã掻çšããŸãã
- ã¡ã¢ãªã¢ãã«ãçè§£ããïŒããã»ããµã¢ãŒããã¯ãã£ãã³ã³ãã€ã©ã«ãã£ãŠã¡ã¢ãªã¢ãã«ã¯ç°ãªããŸããã¡ã¢ãªæäœãã©ã®ããã«é åºä»ããããä»ã®ã¹ã¬ããããèŠããããçè§£ããããšã¯ãæ£ç¢ºæ§ã®ããã«äžå¯æ¬ ã§ãã
- ABAåé¡ã«å¯ŸåŠããïŒCASã䜿çšããå Žåã¯ãéåžžã¯ããŒãžã§ã³ã«ãŠã³ã¿ãã¿ã°ä»ããã€ã³ã¿ã䜿çšããŠãABAåé¡ã軜æžããæ¹æ³ãåžžã«èæ ®ããŠãã ããã
- å ç¢ãªã¡ã¢ãªè§£æŸãå®è£ ããïŒæåã§ã¡ã¢ãªã管çããå Žåã¯ãå®å šãªã¡ã¢ãªè§£æŸæŠç¥ãçè§£ããæ£ããå®è£ ããããšã«æéãæè³ããŠãã ããã
- 培åºçã«ãã¹ãããïŒããã¯ããªãŒã³ãŒããæ£ããå®è£ ããã®ã¯éåžžã«å°é£ã§ããåºç¯ãªåäœãã¹ããçµ±åãã¹ããã¹ãã¬ã¹ãã¹ãã宿œããŠãã ãããäžŠè¡æ§ã®åé¡ãæ€åºã§ããããŒã«ã®äœ¿çšãæ€èšããŠãã ããã
- ïŒå¯èœãªéãïŒã·ã³ãã«ã«ä¿ã€ïŒå€ãã®äžè¬çãªäžŠè¡ããŒã¿æ§é ïŒãã¥ãŒãã¹ã¿ãã¯ãªã©ïŒã«ã€ããŠã¯ãååã«ãã¹ããããã©ã€ãã©ãªå®è£ ããã°ãã°å©çšå¯èœã§ããããããããŒãºãæºããå Žåã¯ãè»èŒªã®åçºæãããã®ã§ã¯ãªãããããã䜿çšããŠãã ããã
- ãããã¡ã€ãªã³ã°ãšæž¬å®ïŒããã¯ããªãŒãåžžã«é«éã§ãããšä»®å®ããªãã§ãã ãããã¢ããªã±ãŒã·ã§ã³ããããã¡ã€ãªã³ã°ããŠå®éã®ããã«ããã¯ãç¹å®ããããã¯ããªãŒãšããã¯ããŒã¹ã®ã¢ãããŒãã®ããã©ãŒãã³ã¹ãžã®åœ±é¿ã枬å®ããŠãã ããã
- å°éç¥èãæ±ããïŒå¯èœã§ããã°ãããã¯ããªãŒããã°ã©ãã³ã°ã®çµéšè±å¯ãªéçºè ãšååããããå°éçãªãªãœãŒã¹ãåŠè¡è«æãåç §ããŠãã ããã
çµè«
ã¢ãããã¯æäœã«ãã£ãŠæ¯ããããããã¯ããªãŒããã°ã©ãã³ã°ã¯ã髿§èœã§ã¹ã±ãŒã©ãã«ããã€èé害æ§ã®é«ã䞊è¡ã·ã¹ãã ãæ§ç¯ããããã®é«åºŠãªã¢ãããŒããæäŸããŸããã³ã³ãã¥ãŒã¿ã¢ãŒããã¯ãã£ãšäžŠè¡æ§å¶åŸ¡ã«é¢ããããæ·±ãçè§£ãèŠæ±ããŸãããã¬ã€ãã³ã·ã«ææã§é«ç«¶åãªç°å¢ã«ããããã®å©ç¹ã¯åŠå®ã§ããŸãããæå 端ã®ã¢ããªã±ãŒã·ã§ã³ã«åãçµãã°ããŒãã«ãªéçºè ã«ãšã£ãŠãã¢ãããã¯æäœãšããã¯ããªãŒèšèšã®ååãç¿åŸããããšã¯ããŸããŸã䞊ååããäžçã®èŠæ±ã«å¿ãããããå¹ççã§å ç¢ãªãœãããŠã§ã¢ãœãªã¥ãŒã·ã§ã³ã®åµé ãå¯èœã«ãããéèŠãªå·®å¥åèŠå ãšãªãåŸãŸãã