é廿°é±éãç§ã¯Rustã§ã®
ããŒã¿äžŠååã®ããã®å®éšã©ã€ãã©ãªã§ãã
Rayonã®æŽæ°ã«åãçµãã§ããŸãã
éçºãã©ã®ããã«é²ãã§ãããã«éåžžã«æºè¶³ããŠããã®ã§ãç§ã¯ããã°æçš¿ã«æ¥ãçç±ã説æããããšã«ããŸããã
Rayonã®ç®æšã¯ãã·ãªã¢ã«ã³ãŒãã«äžŠååŠçãç°¡åã«è¿œå ã§ããããã«ããããšã§ããããã«ããã
for
ã«ãŒããŸãã¯å埩åãè€æ°ã®ã¹ã¬ããã§åäœãããããšãã§ããŸãã ããšãã°ããã®ãããªã€ãã¬ãŒã¿ã®ãã§ãŒã³ãããå ŽåïŒ
let total_price = stores.iter() .map(|store| store.compute_price(&list)) .sum()
次ã«ãéåžžã®
ãã·ãªã¢ã«ã€ãã¬ãŒã¿ããã¬ãŒãšã³ãã
ããã©ã¬ã«ã€ãã¬ãŒã¿ãã«å€æŽããã ãã§ãäœæ¥ã䞊ååã§ããŸãã
let total_price = stores.par_iter() .map(|store| store.compute_price(&list)) .sum()
ãã¡ããã䞊ååŠçãåçŽã«ããã ãã§ã¯ååã§ã¯ãªããå®å
šã«ããå¿
èŠããããŸãã
Rayonã¯ãAPIã䜿çšããŠãããŒã¿ã®ç«¶åãçºçããªãããã«ããŸãããã®æçš¿ã§ã¯ãRayonã®ä»çµã¿ã«ã€ããŠèª¬æããŸãã æåã«ãåºæ¬çãªã¬ãŒãšã³ïŒ
join
ïŒããªããã£ãã«ã€ããŠèª¬æããæ¬¡ã«ãã®å®è£
æ¹æ³ã«ã€ããŠèª¬æããŸãã
Rustã®å€ãã®æ©èœãçµã¿åãããããšã«ãããããã°ã©ã ã®å®è¡äžã«éåžžã«äœããªãŒããŒãããã§
join
ãå®è£
ãã€ã€ãå³å¯ãªã»ãã¥ãªãã£ã確ä¿ã§ããããšã«æ³šæãæããããšæããŸãã æ¬¡ã«ã
join
åºã¥ããŠäžŠåã€ãã¬ãŒã¿ã®æœè±¡åãã©ã®ããã«æ§ç¯ãããããç°¡åã«èª¬æããŸãã
ãã ããã¬ãŒãšã³ã¯ããã«
éçºäžã§ããããšã匷調ããããšæããŸãã çŸåšã®å®è£
ã¯ç§ãæãã»ã©æè»ã§ã¯ãªãã®ã§ã䞊åã€ãã¬ãŒã¿ãŒã®èšèšã¯ãããå€ãã®ãäŸãã°å埩ïŒããããªãïŒãçµãããšã«ãªããšæåŸ
ããŠããŸãã ããã«ãç¹ã«ãããã¯ã®åºããããªãœãŒã¹ã®ã¯ãªãŒã³ã¢ãããªã©ãæ£ããåŠçãããªãç¹æ®ãªã±ãŒã¹ãããã€ããããŸãã ããã«ãããããããRayonã¯çŸåšãç¹å®ã®ã¿ã¹ã¯ã«åœ¹ç«ã€ããšããããŸãã ããªãã幞ãã«ãªãããšãé¡ã£ãŠãç§ã¯ãšãŠã幞ãã§ãïŒ
ãã©ã€ããªã¬ãŒãšã³ïŒããªããã£ãã«åå
æçš¿ã®åé ã§ãmap-reduceæäœã«äžŠåã€ãã¬ãŒã¿ãŒã䜿çšããäŸã瀺ããŸããã
let total_price = stores.par_iter() .map(|store| store.compute_price(&list)) .sum()
ãã ããå®éã«ã¯äžŠåã€ãã¬ãŒã¿ã¯ãããåºæ¬çãªããªããã£ã
join
åºã¥ããŠæ§ç¯ãããåãªãã©ã€ãã©ãªã§ãã
join
䜿çš
join
éåžžã«ç°¡åã§ãã 以äžã«ç€ºãããã«ã2ã€ã®ã¯ããŒãžã£ãŒãåŒãèµ·ããããããã䞊åã«å®è¡
join
å¯èœæ§ããããŸãã äž¡æ¹ãå®äºãããšããã«ãçµæãè¿ãããŸãã
ããã§ã®äž»ãªãã€ã³ãã¯ã2ã€ã®ã¯ããŒãžã£ãŒ
ãæœåšçã«äžŠè¡ããŠå®è¡
ã§ããããšã§ãïŒ
䞊åã¹ã¬ããã䜿çšãããã©ããã®
決å®ã¯ã空ãã«ãŒãã«ããããã©ããã«å¿ããŠåçã«è¡ãããŸãã join
䜿çšããŠãããã°ã©ã å
ã§äžŠååŠçã圹ç«ã€å Žæ
join
ããŒã¯ããã©ã€ãã©ãªã§å®è¡æã«ããã䜿çšãããã©ãããæ±ºå®ã§ããããã«
join
ãšããèãæ¹ã§ãã
æœåšçãªäžŠè¡æ§ã®ã¢ãããŒãã¯ãã¬ãŒãšã³ã
éãããã¯ãã¹ããŒã ãããŒãšåºå¥ããåºæ¬çãªèãæ¹ã§ãã ã¯ãã¹ããŒã ã§ã2ã€ã®å¶éãããã¹ã¬ããéã§äœæ¥ã忣ããå Žåãåžžã«ç°ãªãã¹ã¬ããã§äžŠè¡ããŠå®è¡ãããŸãã åæã«ãRayonã§
join
ãåŒã³åºããŠããå¿
ããã䞊åã³ãŒããå®è¡ããããšã¯éããŸããã ãã®çµæãããã·ã³ãã«ãªAPIã ãã§ãªãããªãœãŒã¹ãããå¹ççã«äœ¿çšã§ããŸãã ããã¯ã䞊ååãæçã«ãªãææãäºåã«äºæž¬ããããšãéåžžã«é£ããããã§ãã ããã«ã¯åžžã«ã°ããŒãã«ã³ã³ããã¹ãã®ç¥èãå¿
èŠã§ããããšãã°ãã³ã³ãã¥ãŒã¿ãŒã«ã¯ç¡æã®ã«ãŒãã«ããããçŸåšå®è¡ãããŠããä»ã®äžŠåæäœã¯äœã§ããïŒ
å®éããã®æçš¿ã®äž»ãªç®æšã®1ã€ã¯ãå
ã»ã©èŠã
ä¿èšŒãããåæå®è¡æ§ãšã¯å¯Ÿç
§çã«ã
Rustã®ããŒã¿åæå®è¡æ§ã®ã©ã€ãã©ãªã®åºç€ãšããŠæœåšçãªåæå®è¡æ§ãä¿é²ããããšã§ãã
ããã¯ãã¯ãã¹ããŒã ãæäŸããä¿èšŒãããäžŠåæ§ã®ããã®å¥åã®åœ¹å²ããªãããšã¯èšããŸã§ããããŸããã
æœåšçãªäžŠè¡æ§ã®ã»ãã³ãã£ã¯ã¹ã¯ã䞊åã¯ããŒãžã£ãŒãã§ããããšã«ãããã€ãã®å¶éã課ããŸãã ããšãã°ããã£ãã«ã䜿çšããŠ
join
2ã€ã®ã¯ããŒãžã£éã§éä¿¡ããããšãããšãã»ãšãã©ã®å Žåãããããã¯ãçºçããŸãã
join
ãéåžžã¯é 次ã¢ã«ãŽãªãºã ã§äžŠååŠçã䜿çšããããã®ãã³ããšããŠèãã䟡å€ããããŸãã æã«ã¯ããã¯ããªããæããã®ã§ã¯ãªã-ããã€ãã®ã¢ã«ãŽãªãºã ã¯æåã¯
䞊åã§ãã ã ïŒãã ãã
join
å
ãã
Mutex
ã
AtomicU32
ãªã©ã®åã䜿çšããããšã¯å®å
šã«éåžžã§ããããšã«æ³šæããŠãã ããã1ã€ã®ã¯ããŒãžã£ãŒãå¥ã®ã¯ããŒãžã£ãŒãåŸ
æ©ããã®ã
ãããã¯ããããªãã ãã§ããïŒ
çµåäŸïŒäžŠåã¯ã€ãã¯ãœãŒã
join
ããªããã£ãã¯
ãã¢ã«ãŽãªãºã ã
åå²ããŠåŸæããã®ã«çæ³ç
ã§ã ã ãããã®ã¢ã«ãŽãªãºã ã¯ãäœæ¥ãã»ãŒçããéšåã«åå²ããååž°çã«å®è¡ããŸãã ããšãã°
ãquicksortã®äžŠåããŒãžã§ã³ãå®è£
ã§ããŸãã
fn quick_sort<T:PartialOrd+Send>(v: &mut [T]) { if v.len() > 1 { let mid = partition(v); let (lo, hi) = v.split_at_mut(mid); rayon::join(|| quick_sort(lo), || quick_sort(hi)); } } fn partition<T:PartialOrd+Send>(v: &mut [T]) -> usize {
å®éããã®ããŒãžã§ã³ã®ã¯ã€ãã¯ãœãŒããšã·ãªã¢ã«ããŒãžã§ã³ã®å¯äžã®éãã¯ã
rayon::join
åŒã³åºã
rayon::join
ãŸãã
çµåã®å®è£
æ¹æ³ïŒççš
å
éšçã«ã
join
ãžã§ã代è¡åä¿¡ãšåŒã°ããææ³ã䜿çšããŠå®è£
ãã
ãŸãã ç§ã®ç¥ãéããäœæ¥ã®ååã¯
Cilkãããžã§ã¯ãã®äžéšãšããŠæåã«å°å
¥ããããã以æ¥ãããªãæšæºçãªææ³ã«ãªããŸããïŒå®éãã¬ãŒãšã³
ïŒããã¹ã³ãŒã¹ãããã·ã«ã¯ãããã·ã«ã¯ãã -çŽTranslãïŒ -Cilkãžã®ãªããŒãžã¥ã
äž»ãªã¢ã€ãã¢ã¯ã
join(a, b)
åŒã³åºããã³ã«
join(a, b)
å®å
šã«äžŠè¡ããŠå®è¡ã§ãã2ã€ã®ã¿ã¹ã¯
a
ãš
b
ãå®çŸ©ããããšã§ããããã®ããã®ç©ºãã¹ã¬ããããããã©ããã¯ãŸã ããããŸããã çŸåšã®ã¹ã¬ãããè¡ãããšã¯ã
ãã¹ã±ãžã¥ãŒã«ããããžã§ãããã¥ãŒã«
b
ã远å ããã ãã§ããã®åŸ
b
ãååŸããŠããã«å®è¡
a
ãŸãã åæã«ãä»ã®ã¢ã¯ãã£ããªã¹ã¬ããã®ããŒã«ããããŸãïŒéåžžãCPUã³ã¢ããšã«1ã€ã®ã¹ã¬ããããŸãã¯ãã®ãããªãã®ïŒã ã¹ã¬ããã®1ã€ãè§£æŸããããšããã«
ãä»ã®ã¹ã¬ããã®
ãèšç»ãããäœæ¥ãã®ãã¥ãŒã«å
¥ããã¿ã¹ã¯ãããã°ãããªãŒã¹ã¬ãããããããã£ããã£ããŠããèªäœãå®è¡ããŸãã ãããã£ãŠããã®å Žåãæåã®ã¹ã¬ããã
a
å®è¡ã§ããžãŒã§
a
ãå¥ã®ã¹ã¬ããã
b
å®è¡ãéå§ã§ããŸãã
æåã®ã¹ã¬ããã
a
çµäº
a
ãšããã«ãä»ã®èª°ãã
b
å®è¡ãéå§ããŸãããïŒ ããã§ãªãå Žåã圌ã¯èªåã§ãããè¡ããŸãã ãã®å Žåãå¥ã®ã¹ã¬ãããçµäºãããŸã§åŸ
æ©ããå¿
èŠããããŸãã ããããæåã®ã¹ã¬ãããåŸ
æ©ããŠããéãå¥ã®ã¹ã¬ããããäœæ¥ã奪ãåããããã«ãã£ãŠå
šäœã®äœæ¥ããã»ã¹ã®å®äºã«è²¢ç®ã§ããŸãã
Rustã®ãããªæ¬äŒŒã³ãŒãã®åœ¢åŒã§ã¯ã
join
ã¯æ¬¡ã®ããã«ãªããŸãïŒ
å®éã®ã³ãŒãã¯å°ãç°ãªããŸããããšãã°ãåæäœã§çµæãåŸãããšãã§ããŸãïŒã
fn join<A,B>(oper_a: A, oper_b: B) where A: FnOnce() + Send, B: FnOnce() + Send, { // `oper_b` , : let job = push_onto_local_queue(oper_b); // `oper_a` : oper_a(); // Check whether anybody stole `oper_b`: if pop_from_local_queue(oper_b) { // , . oper_b(); } else { // , . // : while not_yet_complete(job) { steal_from_others(); } result_b = job.result(); } }
ãžã§ããã£ããã£ãéåžžã«ãšã¬ã¬ã³ãã«ããŠããã®ã¯ãCPUè² è·ãžã®èªç¶ãªé©å¿ã§ãã ã€ãŸãããã¹ãŠã®ã¯ãŒã«ãŒã¹ã¬ãããããžãŒã®å Žåã
join(a, b)
ã¯ãã¹ãŠã®ã¯ããŒãžã£ãŒãé çªã«å®è¡ãå§ããŸãïŒã€ãŸã
a(); b();
ïŒãããã¯ã·ãªã¢ã«ã³ãŒãããæªããããŸããã ããããããªãŒã¹ã¬ãããããå Žåã¯ã䞊åå®è¡ã«ãªããŸãã
ããã©ãŒãã³ã¹æž¬å®
ã¬ãŒãšã³ã¯ãŸã éåžžã«è¥ãããããã¹ãããã°ã©ã ã¯ããŸããããŸããïŒãŸã æé©åããŠããŸããïŒã ããã«ããããããããã§ã«é¡èãªå éãåŸãããšãã§ããŸããããã®ããã«ã¯ããããã°ã«
å°ãæéããããå¿
èŠããããŸãã ããšãã°
ãã¯ã€ãã¯ãœãŒãã®
æŽæ°ããŒãžã§ã³ã§ã¯ã4ã³ã¢Macbook Proã§ã®
䞊åå®è¡ã«ããæ¬¡ã®
å éãèŠãããŸãïŒãããã£ãŠã4åã®å éãæåŸ
ã§ããæå€§å€ã§ãïŒã
é
åã®é·ã | å é |
---|
1K | 0.95x |
32K | 2.19x |
64K | 3.09x |
128K | 3.52å |
512K | 3.84x |
1024K | 4.01x |
å
ã®ããŒãžã§ã³ãšæ¯èŒããŠè¡ã£ã倿Ž-
ç§»è¡ãã·ãŒã±ã³ã·ã£ã«ã¢ã«ãŽãªãºã ã«è¿œå ããŸããã äžçªäžã®è¡ã¯ãå
¥åé
åãååã«å°ããå ŽåïŒç§ã®ã³ãŒãã§ã¯5000ãšã¬ã¡ã³ãæªæºïŒã
join
åŒã³åºããæåŠããŠãã¢ã«ãŽãªãºã ã®ã·ãŒã±ã³ã·ã£ã«ããŒãžã§ã³ã«ç§»åãã
join
ã§ãã ããã¯
ãç§ã®äŸã®ã³ãŒããããããããã«ãã³ãŒããç¹æ§ãšãŸã£ããéè€ãããããšãªãè¡ãããšãã§ããŸãã ïŒèå³ãããã°ããã®èšäºã®æåŸã«ããä»é²ã§ã¢ã€ãã¢ã説æããŸããïŒ
ããã€ãã®æé©åã®åŸãã·ãŒã±ã³ã·ã£ã«å®è¡ãžã®ç§»è¡ãããã»ã©é »ç¹ã«å¿
èŠãšãããªãããšãé¡ã£ãŠããŸãããé«ã¬ãã«ã®APIïŒåè¿°ã®äžŠåã€ãã¬ãŒã¿ãŒãªã©ïŒãã·ãŒã±ã³ã·ã£ã«å®è¡ãžã®ç§»è¡ãè¡ãããšãã§ãããããåžžã«èããå¿
èŠã¯ãããŸããã
ãããã«ãããã·ãŒã±ã³ã·ã£ã«å®è¡ã«ç§»è¡ããªããšãçµæã¯ããã»ã©è¯ããããŸããããã¯ããã«æªãçµæã«ãªãå¯èœæ§ããããŸãã
é
åã®é·ã | å é |
---|
1K | 0.41x |
32K | 2.05x |
64K | 2.42x |
128K | 2.75x |
512K | 3.02x |
1024K | 3.10x |
ç¹ã«ããã®ããŒãžã§ã³ã®ã³ãŒãã¯ã
䞊ååŠçã®ããã«ãã¹ãŠã®ãµãé
åããŠãããé·ãŸã§éä¿¡ããããšã«æ³šæããŠãã ããã é
åã512KãŸãã¯1024Kã®é·ãã§ããå Žåãå€ãã®ãµãã¢ã¬ã€ãäœæãããŸããããã¯å€ãã®ã¿ã¹ã¯ãæå³ããŸãããæå€§3.10åã®å éãåŸãããŸãã ã³ãŒããéåžžã«ããŸãå®è¡ãããçç±ã¯ã次ã®éšåã§èª¬æããããã«ã
åºæ¬çãªã¢ãããŒããæ£ããããã ãšæããŸããRayonã¯ã¡ã¢ãªã®å²ãåœãŠãšä»®æ³ãã£ã¹ããããåé¿ããŸãã ããã§ãã1Kã¢ã¬ã€ã§ã¯0.41xãããåªããããã©ãŒãã³ã¹ãæã¿ãŸãïŒãããŠããã¯å¯èœã ãšæããŸãïŒã
Rustæ©èœã䜿çšããŠãªãŒããŒããããæå°éã«æãã
äžèšãããããããã«ããã®ã¹ããŒã ãåäœå¯èœã«ããã«ã¯ãã¿ã¹ã¯ãããŒã«ã«ãã¥ãŒã«é
眮ãããªãŒããŒãããã³ã¹ããå¯èœãªéãåæžããå¿
èŠããããŸãã æçµçã«ãããã»ããµã®æ°ã¯ã¿ã¹ã¯ã®æ°ãããã¯ããã«å°ãªããããã»ãšãã©ã®ã¿ã¹ã¯ã¯ã€ã³ã¿ãŒã»ãããããªãããšãäºæ³ãããŸãã Rayon APIã¯ãRustã®ããã€ãã®æ©èœã䜿çšããŠãã®ãªãŒããŒããããåæžããããã«èšèšãããŠããŸãã
join
ããã®åŒæ°ã®ã¯ããŒãžã£ãŒã¿ã€ãã«é¢ããŠããªã¢ãŒãã£ãã¯ã§ãã ãããŠããã¯ã åçžåã®éçšã§ãç¹å®ã®ååŒã³åºãã«ç¹åãã join
åå¥ã®ã³ããŒãäœæãããããšãæå³ããŸãã ããã«ããã join
ãoper_a()
ããã³oper_b()
åŒã³åºãoper_a()
ããããã€ã³ã¿ãŒã»ãããããæ¯èŒçãŸããªã±ãŒã¹ãšã¯ç°ãªããŸãïŒãåŒã³åºãã¯éçã«ãã£ã¹ãããããããšããäºå®ã«ã€ãªãããŸããã€ãŸããã€ã³ã©ã€ã³ã«ãªããŸãã ã¯ããã¯ããŒãžã£ãäœæããããã«ã¡ã¢ãªãå²ãåœãŠãå¿
èŠã¯ãããŸãããjoin
ã¯äž¡æ¹ã®ã¯ããŒãžã£ãŒãå®äºãããŸã§å®è¡ããããã¯ãããããã¹ã¿ãã¯äžã®é
眮ãæå€§éã«æŽ»çšã§ããŸã ã ããã¯ãAPIãŠãŒã¶ãŒãšå®è£
ã®äž¡æ¹ã«é©ããŠããŸããããšãã°ãäžèšã®ã¯ã€ãã¯ãœãŒãã®äŸã¯ãå
¥åã«æž¡ããã&mut [T]
ã¹ã©ã€ã¹ãžã®ã¢ã¯ã»ã¹ã«åºã¥ããŠããŸããããã¯ã join
ããã¯ã«ããå¯èœã§ãã åæã«ã join
å®è£
ã¯ãããŒãããã®ã¡ã¢ãªã®å²ãåœãŠãå®å
šã«åé¿ã ãã¹ã¿ãã¯ã®ã¿ã䜿çšã§ããŸãïŒããšãã°ãããŒã«ã«ã¿ã¹ã¯ãã¥ãŒã«é
眮ãããã¯ããŒãžã£ãŒãªããžã§ã¯ãã¯ã¹ã¿ãã¯ã«é
眮ãããŸãïŒã
äžèšãããããããã«ãæçš¿ã¿ã¹ã¯ã®ãªãŒããŒãããã¯éåžžã«äœããªã£ãŠããŸãããç§ãæãã»ã©ã§ã¯ãããŸããã ããããããã«æžããã«ã¯ããã€ãã®æ¹æ³ããããŸãã
- å€ãã®äœæ¥ä»£è¡åä¿¡ã®å®è£
ã§ã¯ã䞊ååŠçã®ããã«ã¿ã¹ã¯ãã¿ã¹ã¯ãã¥ãŒã«é
眮ããããšãã¹ããããããã©ãããæ±ºå®ãããšãã«ããã¥ãŒãªã¹ãã£ãã¯ã䜿çšããŸãã ããšãã°ãäœæ¥Lazy Tzannes Planning ã§ã¯ ãäœæ¥ãã€ã³ã¿ãŒã»ããã§ãã空ãã¯ãŒã«ãŒã¹ã¬ããïŒ ã空è
¹ãã¹ã¬ãããšåŒã°ããïŒããªãå Žåããã¥ãŒã«ã¿ã¹ã¯ãé
眮ããªãããã«ããŸããã
- ãããŠããã¡ãããå€ãè¯ãæé©åã圹ç«ã¡ãŸãã ããšãã°ã
join
ã³ã³ãã€ã«join
ãšãã«ååŸããLLVMãããã³ãŒããã¢ã»ã³ãã©ã³ãŒãã調ã¹ãããšããªããããã§æé©åããã®ãæãç°¡åãªããã§ãã
ããŒã¿ã¬ãŒã¹ã®èªç±
ã¬ãŒãšã³ã¯ããŒã¿ã¬ãŒã¹ããã®èªç±ãä¿èšŒããããšãå
ã«è¿°ã¹ãŸããã ããã¯ãåçŸããã®ãé£ããå¥åŠãªãã°ãå¿é
ããããšãªãã以åã®ã·ãŒã±ã³ã·ã£ã«ã³ãŒãã«äžŠåæ§ã远å ã§ããããšãæå³ããŸãã
å¿é
ããå¿
èŠããããšã©ãŒã«ã¯2ã€ã®ã¿ã€ãããããŸãã ãŸãã2ã€ã®ãã©ãŒã«ããåãå¯å€ç¶æ
ã䜿çšã§ããããã1ã€ã®ã¹ã¬ããã§è¡ããã倿Žãä»ã®ã¹ã¬ããã«åœ±é¿ãäžããå¯èœæ§ããããŸãã ããšãã°ãäž¡æ¹ã®ã¯ããŒãžã£ãŒã§
lo
ãã©ã¡ãŒã¿ãŒãæå®ããŠ
quick_sort
ãïŒèª€ã£ãŠïŒ
quick_sort
ããã«äžèšã®äŸã倿Žããå Žåãã³ãŒããã³ã³ãã€ã«ãããªãããšãé¡ã£ãŠããŸãã
fn quick_sort<T:PartialOrd+Send>(v: &mut [T]) { if v.len() > 1 { let mid = partition(v); let (lo, hi) = v.split_at_mut(mid); rayon::join(|| quick_sort(lo), || quick_sort(lo));
å®éããã®ãšã©ãŒã衚瀺ãããŸãã
test.rs:14:10: 14:27 error: closure requires unique access to `lo` but it is already borrowed [E0500] test.rs:14 || quick_sort(lo)); ^~~~~~~~~~~~~~~~~
äžæ¹ã®ã¯ããŒãžã£ãŒã§
lo
ïŒãŸãã¯
hi
ïŒãåŠçããããäžæ¹ã®ã¯ããŒãžã£ãŒã§
v
ãåŠçããããšãããšãåæ§ã®ãšã©ãŒãçºçããŸããããã¯äž¡æ¹ã®ã¹ã©ã€ã¹ãšéãªããŸãã
泚ïŒãã®äŸã¯äººçºçãªããã«èŠããŸãããå®éã«ã¯ã䞊åã€ãã¬ãŒã¿ãŒãå®è£
ãããšãã«äžåºŠèš±å¯ããïŒãŸãã¯èš±å¯ããïŒå®éã®ãã°ã§ãããããã«ã€ããŠã¯åŸã§èª¬æããŸãã ã³ããŒãšè²Œãä»ãã§ãã®ãããªééããç¯ãã®ã¯éåžžã«ç°¡åã§ãRustãããããäžå¯èœãªã€ãã³ãã«å€ããããã°ã©ã ã®ã¯ã©ãã·ã¥ã«ãããã°ã«å€ããªãããšã¯éåžžã«è¯ãããšã§ãã
ãã£ããã§ããå¥ã®çš®é¡ã®ãã°ã¯ã
join
ã®ã¯ããŒãžã£ãŒã®1ã€ããã®ã¹ã¬ããã»ãŒãã§ãªãã¿ã€ãã®äœ¿çšã§ãã ããšãã°ãRustã¯
Rc
ãšåŒã°ãã
éåååç
§ã«ãŠã³ã¿ãŒãæã€
åãæäŸããŸãã
Rc
ã¯éã¢ãããã¯åœä»€ã䜿çšããŠåç
§ã«ãŠã³ããæŽæ°ããããã
Rc
ãç°ãªãã¹ã¬ããéã§åå²ããããšã¯å®å
šã§ã¯ãããŸããã æ¬¡ã®äŸã®ããã«èª°ããããããšãããšãåç
§ã«ãŠã³ã¿ãç°¡åã«äžæ£ã«ãªããã¡ã¢ãªãäºéã«è§£æŸãããããããã«æªåããå¯èœæ§ããããŸãã
fn share_rc<T:PartialOrd+Send>(rc: Rc<i32> {
ãããããã¡ããããã®äŸãã³ã³ãã€ã«ããããšãããšããšã©ãŒãçºçããŸãã
test.rs:14:5: 14:9 error: the trait `core::marker::Sync` is not implemented for the type `alloc::rc::Rc<i32>` [E0277] test.rs:14 rayon::join(|| something(rc.clone()), ^~~~~~~~~~~ test.rs:14:5: 14:9 help: run `rustc --explain E0277` to see a detailed explanation test.rs:14:5: 14:9 note: `alloc::rc::Rc<i32>` cannot be shared between threads safely
ã芧ã®ãšããã
ãã¡ã¢ãã®åŸã®æåŸã®æçš¿
ã§ãã³ã³ãã€ã©ã¯ãç°ãªãã¹ã¬ããéã§
Rc
ãžã®ã¢ã¯ã»ã¹ãå
±æã§ããªãããšã瀺ããŠããŸãã
join
颿°ããããã®äžå€æ¡ä»¶ã®äž¡æ¹ããµããŒãã§ããã®ã¯ã©ã®ãããªããŒã¯ããžãã¯ã§ããïŒ å®éãçãã¯é©ãã»ã©ç°¡åã§ãã åã
&mut
ã¹ã©ã€ã¹ã2ã€ã®ç°ãªãã¯ããŒãžã£ãŒã«è»¢éããããšãããšãã«åãåã£ãæåã®ãšã©ãŒã¯ãåºæ¬åã·ã¹ãã Rustã«ç±æ¥ããŸãïŒåæã«ååšããåæã«åã
&mut
ã¢ã¯ã»ã¹ã§ãã2ã€ã®ã¯ããŒãžã£ãŒãæã€ããšã¯ã§ããŸãã
ã«ããããŸãã ããã¯ã
&mut
ããŒã¿ãžã®ã¢ã¯ã»ã¹ã
äžæã§ããå¿
èŠãããããã§ããã€ãŸããåã
&mut
å€ãžã®
äžæã®ã¢ã¯ã»ã¹ãæã€2ã€ã®ã¯ããŒãžã£ãããå Žåãå€ã¯ããã»ã©
äžæã§ã¯ãããŸããã
ïŒå®éãããã¯Ruståã·ã¹ãã ã§äœæ¥ããéã®
æå€§ã®æŽå¯ã® 1ã€ã§ããããã以åã¯ãã·ãŒã±ã³ã·ã£ã«ããã°ã©ã ãš
ãããŒã¿ã¬ãŒã¹ãã®
ããã³ã®ã³ã°ãã€ã³ã¿ãŒ ãã¯ãŸã£ããç°ãªãçš®é¡ã®ãã°ã§ãããšèããŠããŸãããã Hydraåç¬ã§ã¯ãåºæ¬çã«ãäž¡æ¹ã®ã¿ã€ãã®ãã°ã«ã¯ãšã€ãªã¢ã¹ãšããŒã¿å€æŽã暪è¡ããŠãããäž¡æ¹ãšãããã¥ã¢ã·ã¹ãã ãšåçšã·ã¹ãã ã䜿çšããŠè§£æ±ºã§ããŸãã
ã§ã¯ãã¹ã¬ããéã§
Rc
ã転éããããšãã2çªç®ã®ãšã©ãŒã¯ã©ãã§ããããã
join
颿°ã§ã¯ãäž¡æ¹ã®ã¯ããŒãžã£ãŒåŒæ°ã
Send
ã¿ã€ããæºããå¿
èŠãããããã«çºçããŸããã Rustã®
Send
ã¯ãã¹ã¬ããéã§ããŒã¿ãå®å
šã«è»¢éã§ããããšãæå³ããŸãã ãããã£ãŠã
join
ãäž¡æ¹ã®ã¯ããŒãžã£ãŒã
Send
ã¿ã€ããæºããå¿
èŠãããããšã宣èšãããšã
ãã¯ããŒãžã£ãŒãã¢ã¯ã»ã¹ã§ããããŒã¿ã®å Žåãããã¹ã¬ããããå¥ã®ã¹ã¬ããã«åãæ¿ããŠãå®å
šã§ããã¯ãã§ãã
ã䞊åã€ãã¬ãŒã¿ãŒ
æçš¿ã®åé ã§ã䞊åã€ãã¬ãŒã¿ãŒã䜿çšããäŸã瀺ããŸããã
let total_price = stores.par_iter() .map(|store| store.compute_price(&list)) .sum();
ããããã以æ¥ãç§ã¯
join
å°å¿µããŠããŸãã å
ã»ã©èšã£ãããã«ã䞊åã€ãã¬ãŒã¿ãŒAPIã¯å®éã«ã¯
join
åçŽãªã©ãããŒã§ãã çŸæç¹ã§ã¯ãããã¯äœãããæ¿çž®ç©ã®ããã«èŠããŸãã ããããæ¬åœã«ãšã¬ã¬ã³ã
ãªã®ã¯ ãäžŠè¡æ§ã«é¢é£ãã
å®å
šã§ãªãã³ãŒããå¿
èŠãšããªãããšã§ãã ã€ãŸãã䞊åã€ãã¬ãŒã¿ãŒAPIã¯åçŽã«
join
ã«åºã¥ããŠæ§ç¯ãããå®å
šã§ãªãã³ãŒãããã¹ãŠé ããŸãã ïŒããæ£ç¢ºã«ã¯ããã¯ãã«ã®æ§ç¯æã«
åæåãããŠããªãã¡ã¢ãªã®ç®¡çã«é¢é£ããå®å
šã§ãªãã³ãŒãã¯ãŸã ã»ãšãã©ãããŸããããããããã®ã³ãŒãã¯
䞊ååŠçãšã¯é¢ä¿ãããŸãããåæ§ã®ã³ãŒãã¯
Vec
å®è£
ã«ãããŸããé©åã«æžãæéããªãã£ãã®ã§ãïŒ
䞊åã€ãã¬ãŒã¿ã®å®è£
ã®è©³çŽ°ã«æ·±ãå
¥ã蟌ã¿ãããããŸãããç§ã®èšç»ã«ãããšãããã¯ãŸã 倿Žãããããã§ãã ããããé«ã¬ãã«ã§ã®èãæ¹ã¯
ãæ¬¡ã®åºæ¬çãªã¡ãœãããæã€
ParallelIterator
ããããšããããšã§ãã
pub trait ParallelIterator { type Item; type Shared: Sync; type State: ParallelIteratorState<Shared=Self::Shared, Item=Self::Item> + Send; fn state(self) -> (Self::Shared, Self::State); ...
ãã®èãæ¹ã¯ãã¡ãœããstate
ãã€ãã¬ãŒã¿ãäžè¬çãªç¶æ
ãšåã
ã®ã¹ã¬ããã®ç¶æ
ã«åå²ãããšãããã®ã§ããäžè¬çãªç¶æ
ã¯ããã¹ãŠã®ã¯ãŒã«ãŒã¹ã¬ããã§ïŒæœåšçã«ïŒå©çšã§ãããããã¿ã€ãã§ããå¿
èŠããããŸãSync
ïŒåæã«è€æ°ã®ã¹ã¬ããããã®å
±æããµããŒãããŸãïŒãåã
ã®ã¹ã¬ããã®ç¶æ
ã¯join
ããžã®åŒã³åºãããšã«åé¢ããããããã¿ã€ãã«ã®ã¿å¿çããSend
å¿
èŠããããŸãïŒå¥ã®ã¹ã¬ããã«å®å
šã«è»¢éã§ããŸãïŒãã¿ã€ã ParallelIteratorState
ã¯ãæ®ãã®äœæ¥ã®äžéšã衚ããŸãïŒããšãã°ãåŠççšã®ãµãã¹ã©ã€ã¹ïŒã圌ã«ã¯3ã€ã®æ¹æ³ããããŸãã pub trait ParallelIteratorState: Sized { type Item; type Shared: Sync; fn len(&mut self) -> ParallelLen; fn split_at(self, index: usize) -> (Self, Self); fn for_each<OP>(self, shared: &Self::Shared, op: OP) where OP: FnMut(Self::Item); }
ãã®ã¡ãœããlen
ã¯ãæ®ã£ãŠããäœæ¥éã®ã¢ã€ãã¢ãæäŸããŸããã¡ãœããsplit_at
ã¯ãã®ç¶æ
ã2ã€ã®éšåã«åå²ããŸãããã®ã¡ãœããfor_each
ã¯ãæå®ãããå埩åããã®ãã¹ãŠã®å€ãåŠçããŸãããããã£ãŠãããšãã°ãã¹ã©ã€ã¹ã®äžŠåã€ãã¬ãŒã¿&[T]
ã¯æ¬¡ã®ããšãè¡ãå¿
èŠããããŸããlen
ã¹ã©ã€ã¹ã®é·ããè¿ãã ãã®å®è£
ãsplit_at
ã¹ã©ã€ã¹ã2ã€ã®ãµãã¹ã©ã€ã¹ã«åå²ããå®è£
ã- ãããŠå®è£
ããŸã
for_each
ãããã¯é
åãéãæããŠåèŠçŽ ã®æäœãåŒãèµ·ãããŸãop
ã
ãããã®äž¡æ¹ã®ç¹æ§ãåããŠãããããåããã¿ãŒã³ã«åŸã£ãŠã³ã¬ã¯ã·ã§ã³ã®äžŠååŠçãå®è£
ã§ããŸããäœæ¥ãã©ãã ãæ®ã£ãŠãããã確èªããå€ãããå Žåã¯ã2ã€ã®éšåã«åå²ããŸãããã以å€ã®å Žåã¯ãã³ã¬ã¯ã·ã§ã³ãé çªã«åŠçããŸãïŒããã«ã¯ãåã«èŠãé çªåŠçãžã®ç§»è¡ãèªåçã«å«ãŸããããšã«æ³šæããŠãã ããïŒã fn process(shared, state) { if state.len() is too big {
ããã§ã¯ãäŸãåç
§ããããšãã§ãããªã³ã¯ãããŠãããã¯ãã«ã®èŠçŽ ã®ã³ã¬ã¯ã·ã§ã³ãããŠ1ã€ã®å€ã«ããŒã¿ã»ã¹ããªãŒã ãæå°éã«æããã«ã¯ãçµè«ãšæŽå²çèæ¯
Rayonã®ææ°ããŒãžã§ã³ã«éåžžã«æºè¶³ããŠããŸãã圌女ã¯éåžžã«äœ¿ãããããéåžžã«è¡šçŸåããããéåžžã«å¹æçã«ãªãå¯èœæ§ãé«ããšæããŸãããŸããRustã§ããŒã¿ã®äžŠååŠçããšã¬ã¬ã³ãã«ãªã£ãããšãå¬ããæããŸããããã¯ãé·ãé²åãšå€ãã®éçºã®ç¹°ãè¿ãã®çµæã§ããããšãã°ãRustã¯åæã®é ãå
±æã¡ã¢ãªã䜿çšããã«äžŠåã¿ã¹ã¯ããã€ããä»ããŠéä¿¡ããå³å¯ãªã¢ãŒã©ã³ã®ãããªã¢ãããŒãã䜿çšããŠããŸããããã®ã¢ãããŒãã¯ãé«ã¬ãã«ã®ã¢ããªã±ãŒã·ã§ã³ã«ã¯é©ããŠããŸããã䞊åã¯ã€ãã¯ãœãŒããœãŒãã®èšè¿°ã«ã¯é©ããŠããŸããããã ããåã·ã¹ãã ãåŸã
ã«å€æŽããŠããã©ã¬ã«ã¯ã€ãã¯ãœãŒãã®ã·ã³ãã«ã§ã¯ã€ãã¯ãªããŒãžã§ã³ã«ã©ãã©ãè¿ã¥ããããã«ããŸãããç§ã®åæã® ãã¶ã€ã³ãèŠããšãçŸåšã®å埩Rayon
ãçŸæç¹ã§æé©ã§ããããšã¯æããã§ããç§ãç¹ã«æ°ã«å
¥ã£ãŠããã®ã¯ããŠãŒã¶ãŒã ãã§ãªãéçºè
ã«ãšã£ãŠãã·ã³ãã«ãªããšã§ããã€ãŸããRuståã·ã¹ãã ã§ã¯ã¬ã€ãžãŒãªããªãã¯ã䜿çšããããã»ãã¥ãªãã£ãå®çŸããããã«ããºã«åã䜿çšãããããå¿
èŠã¯ãããŸãããããã¯ãèšèªã®2ã€ã®äž»ãªãœãªã¥ãŒã·ã§ã³ã®ãããã§å¯èœã ãšæããŸãã- , . , ,
&mut
, const
- ( , ) ( , Rust , , - , const
â . .) . , Rust , . - Send , RFC458.
Send
, . RFC Send
-: 'static
, . Erlang, , , . - , .
, 'static
Send
, !
ã¢ããªã±ãŒã·ã§ã³ïŒã³ãŒãã®éè€ã䌎ââããªãé æ¬¡å®è¡ãžã®ç§»è¡ã®å®è£
ã¯ã€ãã¯ãœãŒãã®äŸã§ããã©ãŒãã³ã¹ãåäžãããã«ã¯ãé
åãååã«å°ããå Žåã«ã·ãªã¢ã«ã³ãŒããžã®ãžã£ã³ãã䜿çšããå¿
èŠãããããšãåè¿°ããŸããããããã®ã±ãŒã¹ã«2ã€ã®ã¯ã€ãã¯ãœãŒãå®è£
ããããšãéåžžã«ã€ã©ã€ã©ããŸãã幞ããRustç¹æ§ã䜿çšããŠãåããœãŒã¹ã³ãŒããã2ã€ã®ããŒãžã§ã³ã®ã³ãŒããèªåçã«çæã§ããŸãããã®ã¢ããªã¯ããã®äŸã§äœ¿çšããããªãã¯ã説æããŠããŸããæåã«ãJoiner
颿°ããæœè±¡åãããåãå®çŸ©ãããŸãjoin
ïŒ trait Joiner {
ãã®ã¿ã€ãã«ã¯ãã·ãªã¢ã«ããã³ãã©ã¬ã«æäœã¢ãŒãã«å¯Ÿå¿ãã2ã€ã®å®è£
ããããŸãã struct Parallel; impl Joiner for Parallel { .. } struct Sequential; impl Joiner for Sequential { .. }
ããã§ãéžæããå®è£
ïŒã·ãŒã±ã³ã·ã£ã«ãŸãã¯ãã©ã¬ã«ïŒãå®çŸ©ããquick_sort
åã«é¢é£ããããªã¢ãŒãã£ãã¯é¢æ°ãšããŠæžãæããããšãã§ããŸãJ: Joiner
ãå°ããªé
åã®äžŠåããŒãžã§ã³ã¯ã·ãªã¢ã«ã«ãªããŸãïŒ fn quick_sort<J:Joiner, T:PartialOrd+Send>(v: &mut [T]) { if v.len() > 1 {