ã¯ããã«
åå ãããã°ã©ã ã§äœ¿çšå¯èœãªã¡ã¢ãªã人çºçã«å¶éããæ¹æ³ã«ã€ããŠèª¬æããŸããã ããŒãã¹ãšããŠã libmemrestrict-ã¡ã¢ãªäœ¿çšéã远跡ããããã®mallocãªã©ã®é¢æ°ã©ãããŒãåããã©ã€ãã©ãªãããã³ptrace-restrict-åãç®çã§brkãsbrkããã³mmapåŒã³åºããã€ã³ã¿ãŒã»ããããptraceããŒã¹ã®ããŒã«ãå ¥æããŸããã
ããã§ã¯ããªãã¡ã¢ãªå¶éãæŽçããå¿ èŠãããã®ã§ããããïŒ OOMãæåŸã«ã¢ããªã±ãŒã·ã§ã³ãéä»ãã«ããã®ã¯ãã€ã§ããïŒ ããã°ã©ãã³ã°äžã®ã¡ã¢ãªæ¶è²»ã«ã€ããŠåžžã«èããŠããŸããïŒ ã¡ã¢ãªã¯å®äŸ¡ã§ãããã¡ã¢ãªãäžè¶³ããå Žåã¯ãããã«æ°ã®ã¬ãã€ããè¿œå ããŸãã
ããã«ãããããããã¡ã¢ãªãééãªãè¿œå ããããšã¯äžå¯èœã§ããç¡éã®ãœãŒã¹ããªãããã§ã¯ãããŸããã ããã°ããŒã¿ãåŠçããå Žåããã¹ãŠã®å ¥åãé åã«å容ããããšã¯äžå¯èœã§ããRAMãã¹ãã¬ãŒãžã¡ãã£ã¢ããããã¯ãŒã¯éã§ããŒã¿ãåæ£ããå¿ èŠããããŸãã ãã®ãããªããŒã¿åŠçã«ã¯ãã¢ã«ãŽãªãºã ãšæè¡ãå¿ èŠã§ãã
ããã§ãåçŽãªã¿ã¹ã¯ããå§ããŠã2 MiBã®ã¡ã¢ãªã§100äžåã®æŽæ°ïŒ4 MiBããŒã¿ïŒããœãŒãããæ¹æ³ã説æããŸãã ãã®ã¿ã¹ã¯ã¯ããã¹ãŠã®ããŒã¿ãå容ããã®ã«ååãªã¡ã¢ãªããªãå Žåã«äžè¬åã§ããŸãã
äžãããã
ãã¡ã€ã«ã«æ ŒçŽãããŠããæŽæ°ã®ã»ããããœãŒãããããã°ã©ã ãäœæããå¿ èŠããããŸãã ãããäœæããããã«ãæãåçŽãªãŠãŒãã£ãªãã£randintsããã³rangeintsãäœæããŸãã
ããã°ã©ã ã¯ãæšæºåºåã«ããã¹ããšããŠãœãŒããããé åãäœæããå¿ èŠããããŸã
圌女ã¯å®è¡æéã枬å®ããstderrã«åºåããå¿ èŠããããŸãã timeãŠãŒãã£ãªãã£ã䜿çšããŠããã°ã©ã ãå®è¡ããããšã¯ã§ããŸããããã¡ã€ã«ãèªã¿åãæéãšåºåããæéãã«ãŠã³ãããããã§ãã
ãã¡ã€ã«ã®å°ãªããšãååã®ãµã€ãºã§åäœããã¯ãã§ãã ãããè¡ãã«ã¯ãlibmemrestrictãŸãã¯ptrace-restrictã䜿çšããŸãã
äžéšã®æ¹æ³ã§ã¯ããããã®ãŠãŒãã£ãªãã£ã¯åœ¹ã«ç«ã¡ãŸããã ããšãã°ãmmapã§ã¯æ©èœããŸãããã¡ã¢ãªã®äœ¿çšãç©ççã«å¶éããå¿ èŠããããŸãã
å ã®åé¡ã解決ããããã«ãã§ãã¯ãããŸãïŒ4 MiBã2 MiBã«åé¡ããŸãïŒã ãŸãã128 MiBã®ã¡ã¢ãªãæèŒããä»®æ³ãã·ã³ã§å®è¡ããŠã500 MbïŒ1å2,500äžã®4ãã€ãæŽæ°ïŒããœãŒãããŸãã
çŽ æŽãªã¢ãããŒã
æ°å€ãçŽæ¥äžŠã¹æ¿ããŠãã¡ã¢ãªäœ¿çšéïŒããã³æéïŒãèšç®ããŠã¿ãŸãããã ãã¡ã€ã«ãæŽæ°ã®é åã«èªã¿èŸŒã¿ã qsortãåŒã³åºããŸãã
4 MBã®ããŒã¿ãå«ããã¡ã€ã«ãè©ŠããŠã¿ãŸãããã å¶éãªãã§ããã¹ãŠãæ©èœããŸãïŒ
$ ./naive 4M.bin > /dev/null 4000000 bytes sorted in 0.323146 seconds
ããããããã¯é¢çœããããŸããã ã¡ã¢ãª2 MiBã®å¶éïŒ
$ LD_PRELOAD=./libmemrestrict.so ./naive ints > ints.sorted Segmentation fault
å¶éã4 MiBã«äžããŸã-åã³å€±æããŸãã ïŒlibmemrestrictã¯ç°å¢ããèšå®ãèªã¿åããŸãïŒã
$ MR_THRESHOLD=5000000 LD_PRELOAD=./libmemrestrict.so ./naive ints > ints.sorted Segmentation fault
æããã«ãqsortã¯ããå€ãã®ã¡ã¢ãªãå¿ èŠãšããŸãã 圌ãvalgrindã®massifã§ã©ãã ã欲ãããèŠãŠã¿ãŸãããïŒ
$ valgrind --tool=massif ./naive ints $ ms_print massif.out.10676
çŸããã¹ã±ãžã¥ãŒã«ã¯æ¬¡ã®ãšããã§ãã
MB 8.819^ :::::::::::::::::::::::::::# | : # | : # | : # | : # | : # | : # | : # | : # | :::::::@ #:::::::::::::::::::::::: | : @ # | : @ # | : @ # | : @ # | : @ # | @@@@@@: @ # | @ : @ # | @ : @ # | :::@ : @ # | ::: @ : @ # 0 +----------------------------------------------------------------------->Gi 0 1.721
ã¡ã¢ãªãªã¯ãšã¹ãã4 MiBã«åå¢ããè€æ°ã®ããŒã¿é 眮ã確èªã§ããŸãããããç§ã®é åã§ãqsortçšã«ããã«4 MiBã§ãã çµ±èšïŒ
-------------------------------------------------------------------------------- n time(i) total(B) useful-heap(B) extra-heap(B) stacks(B) -------------------------------------------------------------------------------- 21 173,222,581 5,247,504 4,000,568 1,246,936 0 22 173,223,802 5,246,920 4,000,000 1,246,920 0 23 173,226,655 5,247,504 4,000,568 1,246,936 0 24 173,229,202 5,246,920 4,000,000 1,246,920 0 25 173,229,311 9,246,928 8,000,000 1,246,928 0 26 869,058,772 9,246,928 8,000,000 1,246,928 0 86.52% (8,000,000B) (heap allocation functions) malloc/new/new[], --alloc-fns, etc. ->43.26% (4,000,000B) 0x400A26: readfile (in /home/avd/dev/cs/sorting/external/naive) | ->43.26% (4,000,000B) 0x400ACD: main (in /home/avd/dev/cs/sorting/external/naive) | ->43.26% (4,000,000B) 0x35D40383F7: qsort_r (in /usr/lib64/libc-2.18.so) | ->43.26% (4,000,000B) 0x400B3D: main (in /home/avd/dev/cs/sorting/external/naive) | ->00.00% (0B) in 1+ places, all below ms_print's threshold (01.00%)
400äžãã€ããããã«400äžãã€ã-qsort_rã䜿çšããŠããŸãã ããã«ãå¥ã®1.2 MBãããŒãäžã«massifãè¿œå ã§äœ¿çšããŸãã
æããã«ããã®å Žåãqsortã¯ããªã¥ãŒã ã®è€éãã«é¢ããŠOïŒnïŒã®ããã«åäœããŸãã qsortã¯ãã€ã³ãã¬ãŒã¹ãã§åäœããããŸããŸãªæé©åææ³ã䜿çšããŠOïŒlog nïŒã®ããªã¥ãŒã ã®è€éããä¿èšŒãããããããã¯å¥åŠã§ãã glibc qsortã®å®è£ ã«é¢ãã詳现æ å ± ã
ããŠã500 MBã128 MiB RAMã«åé¡ã§ããŸããïŒ
$ ./naive 500M.bin > /dev/null Segmentation fault
ãã¡ããéããŸãã æ§èœïŒ
$ ./naive 4M.bin > /dev/null 4000000 bytes sorted in 0.322712 seconds
ããã¯ãåçŽãªãœãŒããå¶éãªãã§é©åã«æ©èœããå¶éä»ãã§ã¯ãŸã£ããæ©èœãããqsortãOïŒnïŒã¡ã¢ãªãå¿ èŠãšããããšãæå³ããŸãã ããã¯å¥åŠã§ãã ããšãã°ãã¡ã¢ãªã5.3 MBã«å¶éãããšãåäœããOïŒnïŒã¡ã¢ãªãå¿ èŠãšããŸããã ç§ã¯ãŸã ãããæ±ã£ãŠããŸãã
ãã¡ã€ã«ãšmmap
mmapã¯ãã¡ã¢ãªå¶éã®æ¡ä»¶äžã§å€§éã®ããŒã¿ããœãŒãããããã«ãŒã®æ¹æ³ã§ãã ã¡ã¢ãªãšã¹ã¯ããã®éã®ããŒã¿é åžã®è² æ ãOSã®è©ã«ç§»ããŸãã
次ã®ããã«æ©èœããŸãã
- mmapãéããŠããã¡ã€ã«å šäœãã¡ã¢ãªã«éä¿¡ããŸã
- ããŒã¿ãžã®ãã€ã³ã¿ãååŸããŸã
- ãã®ãã€ã³ã¿ã§ããŒã¿ããœãŒãããã¢ã«ãŽãªãºã ãåŒã³åºããŸã
ããã ãã§ãïŒ äœ¿çšå¯èœãªã¡ã¢ãªããã倧ããããªã¥ãŒã ã§ãã¡ã€ã«ããœãŒãããŠããã¡ã¢ãªãªãŒããŒãããŒã¯çºçããŸããã ã¡ã«ããºã ãç解ããã«ã¯ãOSã®ã¡ã¢ãªç®¡çã«ã€ããŠå°ãç解ããå¿ èŠããããŸãã
åããã°ã©ã ã¯ãä»ããåé¢ãããç¬èªã®ä»®æ³ã¢ãã¬ã¹ç©ºéãæã€ããã»ã¹ã«ãã£ãŠè¡šãããŸãã ãã®é·ãã¯CPUãã¹ã®å¹ ã«ãã£ãŠå¶éãããŸããã€ãŸãã32ãããCPUã®å Žåã¯2 32 ãã€ãŸã4 GiBã§ãã
ããã»ã¹ã«é¢ä¿ãããã¹ãŠã®ã¡ã¢ãªå²ãåœãŠã¯ãä»®æ³ã¡ã¢ãªã§çºçããŸãã ãã®ä»®æ³ã¡ã¢ãªã¯ãã¡ã¢ãªãæäœããããã«ã«ãŒãã«ã®ç©çãµãã·ã¹ãã -MMUã«ããããããŸãã éåžžããé 延ãã¢ãŒãã§çºçããŸããã€ãŸããããã»ã¹ãã¡ã¢ãªãèŠæ±ãããšãã«ãŒãã«ã¯ããã«ã¡ã¢ãªãå²ãåœãŠãŸãããç©ççã«å³åº§ã«é 眮ããããšã¯ãããŸãããã€ãŸããä»®æ³ã¡ã¢ãªã®ããŒãžã¯ç©çã«çŽæ¥ãããã³ã°ãããŸããã ãã®ãããªããŒãžã«ã¢ã¯ã»ã¹ãããšïŒããšãã°ãèšé²ã®ããã«ïŒãMMUã¯ãããŒãžãã©ãŒã«ããäŸå€ãçºçãããŸããããã¯ãã«ãŒãã«ãä»®æ³ããŒãžãç©çããŒãžã«ãããã³ã°ããããšã§åŠçããŸãã ããã§è¡šç€ºããããã®ããŒãžã®ã¬ã³ãŒãã¯MMUã«ãã£ãŠç©çã¡ã¢ãªã®ç¹å®ã®ã¢ãã¬ã¹ã®ã¬ã³ãŒããšããŠãããŒããã£ã¹ããããŸãã
äžæ¹ãä»®æ³ã¢ãã¬ã¹ç©ºéãCPUãã¹ã®ãµã€ãºã«ãã£ãŠã®ã¿å¶éãããããšãèŠããŠããå Žåãããã°ã©ã ã䜿çšå¯èœãªã¡ã¢ãªãããå€ãã®ã¡ã¢ãªã䜿çšããããšããç¶æ³ã«é¥ãããšããããŸãã ããšãã°ã256 MiB RAMã®32ãããã·ã¹ãã ã§ã¯ãããã»ã¹ã¯1 GiBã®ã¡ã¢ãªãé 眮ããŠäœ¿çšã§ããŸãã ãã®å Žåãã¡ã¢ãªããŒãžã¯ã¹ã¯ããã«åé¡ãããŸã-RAMã®ä»£ããã«ãããŒããã£ã¹ã¯ãªã©ã®ãã©ã€ãã«ç§»åããŸãã ãã®ãããªããŒãžã«ã¢ã¯ã»ã¹ãããšãã«ãŒãã«ã¯ããããã©ã€ãããèªã¿åããã¡ã¢ãªã«éä¿¡ããŸãïŒã¡ã¢ãªå ã®å¥ã®ããŒãžã眮ãæããŸãïŒã
ã«ãŒãã«ã¯ãã¡ã¢ãªãšãã©ã€ãéã®ããŒã¿ã®åæ£ã«ããŸã察å¿ããŠãããããã¿ã¹ã¯ã§ãã®ããããã£ã䜿çšããããšããã®ã¯èªç¶ãªããšã§ãã ãã¡ã€ã«ã«å¯ŸããŠmmapãåŒã³åºããšãã«ãŒãã«ã¯ãããã«ã¯å²ãåœãŠãããªãä»®æ³ã¢ãã¬ã¹ã®ç¯å²ãäºçŽããŸãã ãããã«ã¢ã¯ã»ã¹ããããšãããšãã«ãŒãã«ã¯ãããå ¥åãã¡ã€ã«ããã¡ã¢ãªã«ããŒãããŸãã ç©çã¡ã¢ãªãäžè¶³ãããšãã«ãŒãã«ã¯ã¹ã¯ããå ã®ããŒãžãåé€ããŸãã ãããã£ãŠããã£ã¹ã¯äžã®ãã¡ã€ã«ãã¡ã¢ãªãããã³ã¹ã¯ããéã§ããŒã¿ã®ãã©ã³ã¹ãåããŸãã
å¶éã¯ä»®æ³ã¢ãã¬ã¹ç©ºéïŒ32ãããã·ã¹ãã ã®å Žåã¯4 GiBã64ãããã®å Žåã¯256 TiBïŒãšã¹ã¯ããã ãã§ããããããä»æ¥ã®ã¹ãã¬ãŒãžããã€ã¹ã¯å®äŸ¡ã§ãã
mmapã¯ãã¡ã€ã«å šäœãä»®æ³ã¡ã¢ãªã«ããŒããããšããäºå®ã«ãããä»®æ³ã¡ã¢ãªèªäœãå¶éãããããlibmemrestrictãŸãã¯ptrace-restrictã䜿çšã§ããŸããã ããªã¥ãŒã ã100Mã®ããŒã¿ãããªã¥ãŒã ã10Mã®ä»®æ³ã¡ã¢ãªã«ãœãŒãããããšãããšãmmapãããšã©ãŒãçºçããŸãã
$ qemu-x86_64 -R 10M ./mmaped 100M.bin mmap stack: Cannot allocate memory
äžæè°ã§ã¯ãããŸãã-ãã¡ã€ã«ã¯ä»®æ³ã¡ã¢ãªã«ããŒããããã«ãŒãã«ã¯ãããç©çã¡ã¢ãªãšã¹ã¯ããã«åé ããŸãã ãã®ãããå°ãªããšã100Mã®ä»®æ³ã¡ã¢ãªãšãqemuçšã®ã¹ããŒã¹ãå¿ èŠã§ãã
ãããã£ãŠããã®æ¹æ³ã§ã¯ã128 MiBã®ã¡ã¢ãªãæã€ä»®æ³ãã·ã³ã䜿çšããŸãã mmapã䜿çšãããœãŒãããã°ã©ã ã次ã«ç€ºããŸãã ãããŠããã¯åäœããŸãïŒ
$ free -m total used free shared buffers cached Mem: 119 42 76 0 4 16 -/+ buffers/cache: 21 97 Swap: 382 0 382 $ ll -h 500M.bin -rw-r--r-- 1 root root 477M Feb 3 05:39 500M.bin $ ./mmaped 500M.bin > /dev/null 500000000 bytes sorted in 32.250000 seconds
äžããã®æ å ±ïŒ
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND 3167 root 20 0 480m 90m 90m R 84.6 76.4 1:18.65 mmaped
500 MBã®ä»®æ³ã¡ã¢ãªã䜿çšããŸãããå®éã«äœ¿çšå¯èœãªã¡ã¢ãªã¯90 MiBã§ãã MiBã¯2 20ã§ãããMBã¯10 6 = 100äžã§ãã 500 MB = 500,000,000ãã€ãã500,000,000 >> 20 = 476 MiBã
500 MBã®ãœãŒãäžã«vmstatã®è©³çŽ°ãèŠããšãã«ãŒãã«ãã¹ã¯ããããã£ã¹ã¯ãã£ãã·ã¥ããããã¡ã空ãã¡ã¢ãªã®éã§ã©ã®ããã«ãã©ã³ã¹ãåã£ãŠããããããããŸãã
procs -----------memory---------- ---swap-- -----io---- -system-- ----cpu---- rb swpd free buff cache si so bi bo in cs us sy id wa 0 0 0 77776 2120 15104 1 27 710 971 24 34 3 1 95 1 1 1 0 2060 488 90068 1 27 785 1057 25 37 3 1 95 1 1 0 928 3400 60 89744 1 27 799 1092 25 38 3 1 94 1 0 2 1908 1928 212 92040 1 27 852 1174 26 40 4 1 94 1 0 2 3436 2360 280 93056 1 27 911 1282 28 42 4 1 94 2 0 0 5272 3688 196 94688 1 27 1066 1471 31 48 4 1 93 2 0 0 5272 3720 204 94700 1 27 1064 1469 31 48 4 1 93 2
æåã«ãçŽ70 MiBã®ç©ºãã¡ã¢ãªã空ã®ã¹ã¯ããããããã¡ã¢ãªã®ããããI / Oãããã¡ãšãã£ãã·ã¥ã«å²ãåœãŠãããŸããã ãã®åŸãmmapåŸããã®ã¡ã¢ãªã¯ãã¹ãŠãã£ãã·ã¥ã«ä¿åãããŸããã 空ãã¡ã¢ãªããªããªããšãã«ãŒãã«ã¯ã¹ã¯ããã®äœ¿çšãéå§ããŸããããã¹ã¯ããã¯I / Oè² è·ã®å¢å ãšãšãã«å¢å ããŸãã ãããŠãã»ãŒãã¹ãŠã®ã¡ã¢ãªããã£ã¹ã¯ãã£ãã·ã¥ã«å²ãåœãŠããããšããçµè«ã«éããŸãããããã¯ãã¢ããªã±ãŒã·ã§ã³ã«ã¡ã¢ãªãå¿ èŠãªå Žåããã£ã¹ã¯ãã£ãã·ã¥ã®ããããŒãžãæåã«ãªããããéåžžã®ããšã§ãã
ãã®ãããmmapã«ãã䞊ã¹æ¿ãã¯ãã¡ã¢ãªã®æäœã«é¢ããåºæ¬çãªã¢ã€ãã¢ãå¿ èŠãšããã¯ãŒã«ãªããã¯ã§ãããå°éã®ã¡ã¢ãªã§å€§éã®ããŒã¿ãåŠçããããã®ç°¡åãªãœãªã¥ãŒã·ã§ã³ãæäŸããŸãã
å€éšããŒãžãœãŒã
mmapã¯äœ¿çšã§ããªããšããŸãããã32ãããã·ã¹ãã ã§5 GiBã®ãã¡ã€ã«ããœãŒãããããšããŸãã
ãå€éšããŒãžãœãŒãããšåŒã°ããããç¥ãããæ¹æ³ããããŸãã ååãªã¡ã¢ãªããªãå Žåã¯ãããŒããã£ã¹ã¯ãªã©ã®å€éšãã©ã€ãã䜿çšããå¿ èŠããããŸãã ããŒã¿ã¯ã¡ã¢ãªã«åãŸããªãããã1ã€ãã€åŠçããå¿ èŠããããŸãã
å€éšããŒãžãœãŒãã¯æ¬¡ã®ããã«æ©èœããŸãã
- å©çšå¯èœãªã¡ã¢ãªã®éã§ããŒã¿ãæçã«åå²ããŸã
- åããŒã¹ã¯ã¡ã¢ãªã§ãœãŒããããå€éšã¡ãã£ã¢ã«æžã蟌ãŸããŸã
- ããã§ãfilesize / buffersizeã®ãµã€ãºã®æçãã§ããŸãã
- ãµã€ãºbuffersize /ïŒãã£ã³ã¯ã®äžéšãèªã¿åãããããããããã¡ã«çµåããçµæããã¡ã€ã«ã«åºåããŸã
ç§ã¯åçŽãªæé©åãããŠããªãå®è£ ãè¡ããŸããïŒ
$ LD_PRELOAD=./libmemrestrict.so ./external-merge 4M.bin 1048576 > /dev/null 4194304 bytes sorted in 0.383171 seconds
2 MiBã®ã¡ã¢ãªã§ãœãŒãããã1 MiBã®ãããã¡ã䜿çšããŸãã
500 MBããœãŒãããŸãã ãŸããããŒã¿ã®äº€æãæåã§å¶åŸ¡ãããããã¹ã¯ãããç¡å¹ã«ããŸãã
$ swapoff /dev/vda5
ãã£ãã·ã¥ããŒãã«ããŸãã
$ echo 3 > /proc/sys/vm/drop_caches
䜿çšå¯èœãªã¡ã¢ãªã確èªããŸãã
$ free -m total used free shared buffers cached Mem: 119 28 90 0 0 6 -/+ buffers/cache: 21 97 Swap: 0 0 0
50 MBã®ãããã¡ã䜿çšããŸã-ãã¡ã€ã«ãµã€ãºã®10åã®ãµã€ãºã§ãã
$ ./external-merge 500M.bin 50000000 > /dev/null 500000000 bytes sorted in 120.115180 seconds
äœãã2åïŒ ã©ãããŠã§ããïŒ ãã¡ãããI / Oæäœãåå ã§ãã 3ã€ã®ããšãããã»ã¹ã劚ããŸãã ããŒã¿åé¢ãã§ãŒãºã§ã¯ãå°ããªãããã¡ãŒã䜿çšããŠãã¡ã€ã«ãé 次èªã¿åããŸãã ããŒãžãã§ãŒãºã§ã¯ãæ å ±ãå«ããã¡ã€ã«ãéãããéãããããŸãã ãŸããçµè«ããããŸããããŒãžãã§ãŒãºã§ã¯ã50 MBã®ããŒã¿ãstdoutã«åºåããŸããããã¯ã/ dev / nullã«ãªãã€ã¬ã¯ããããŸãããè² è·ãäžããŸãã ãããç¡å¹ã«ãããšãããã©ãŒãã³ã¹ã25ïŒ åäžããŸãã
$ ./external-merge-no-output 500M.bin 50000000 > /dev/null 500000000 bytes sorted in 87.140000 seconds
ã¡ã¢ãªã®äœ¿çšã¯ç§ã«ã¯åé¡ãããŸããã massifãä»ããŠããã°ã©ã ãå®è¡ãããšãæ¶è²»ã®ããŒã¯ã¯ãããã¡ãŒã®ãµã€ãºãšå°ããªããŒãã§ããããšãããããŸãã
-------------------------------------------------------------------------------- Command: ./external-merge 500M.bin 50000000 Massif arguments: (none) ms_print arguments: massif.out.17423 -------------------------------------------------------------------------------- MB 47.75^ ::::: |#::::::@:::::::::::@:::::::::@:::@::::@::::@::::::::@::::@::::@:::@ |# : : @ : : : : @ : : @ @ @ @ : @ @ @ @ |# : : @ : : : : @ : : @ @ @ @ : @ @ @ @ |# : : @ : : : : @ : : @ @ @ @ : @ @ @ @ |# : : @ : : : : @ : : @ @ @ @ : @ @ @ @ |# : : @ : : : : @ : : @ @ @ @ : @ @ @ @ |# : : @ : : : : @ : : @ @ @ @ : @ @ @ @ |# : : @ : : : : @ : : @ @ @ @ : @ @ @ @ |# : : @ : : : : @ : : @ @ @ @ : @ @ @ @ |# : : @ : : : : @ : : @ @ @ @ : @ @ @ @ |# : : @ : : : : @ : : @ @ @ @ : @ @ @ @ |# : : @ : : : : @ : : @ @ @ @ : @ @ @ @ |# : : @ : : : : @ : : @ @ @ @ : @ @ @ @ |# : : @ : : : : @ : : @ @ @ @ : @ @ @ @ |# : : @ : : : : @ : : @ @ @ @ : @ @ @ @ |# : : @ : : : : @ : : @ @ @ @ : @ @ @ @ |# : : @ : : : : @ : : @ @ @ @ : @ @ @ @ |# : : @ : : : : @ : : @ @ @ @ : @ @ @ @ |# : : @ : : : : @ : : @ @ @ @ : @ @ @ @ 0 +----------------------------------------------------------------------->Gi 0 332.5 Number of snapshots: 98 Detailed snapshots: [4 (peak), 10, 20, 29, 32, 35, 38, 45, 48, 54, 64, 74, 84, 94] -------------------------------------------------------------------------------- n time(i) total(B) useful-heap(B) extra-heap(B) stacks(B) -------------------------------------------------------------------------------- 0 0 0 0 0 0 1 119,690 584 568 16 0 2 123,141 50,004,496 50,000,568 3,928 0 3 4,814,014 50,005,080 50,001,136 3,944 0 4 4,817,234 50,005,080 50,001,136 3,944 0 99.99% (50,001,136B) (heap allocation functions) malloc/new/new[], --alloc-fns, etc. ->99.99% (50,000,000B) 0x400FA2: external_merge_sort (in /root/external-merge) | ->99.99% (50,000,000B) 0x40128E: main (in /root/external-merge) | ->00.00% (1,136B) in 1+ places, all below ms_print's threshold (01.00%)
ã¡ã¢ãªã50 MBã«å¶éããããã«ãã¡ã€ã«ãã¹ãå«ãäžæè¡ã«ããã«500 KBãå¶éã§ããŸãã
$ LD_PRELOAD=./libmemrestrict.so MR_THRESHOLD=51000000 ./external-merge 500M.bin 50000000 > /dev/null 500000000 bytes sorted in 87.900000 seconds
äžè¬ã«ãã¡ã¢ãªã§ã¯-ããããŸãããé床ã§ã¯-ããããŸããã mmapã¯ãã®æäœã32ç§ã§å®è¡ã§ããŸããã æ¹æ³ãæ¹åããŸãããã
gprofã䜿çšããŠããã°ã©ã ã®ãããã¡ã€ã«ãäœæããŸãããã ãã€ããªãäœæãã
$ gcc -pg -g -Wall -Wextra external-merge.c -o external-merge-gprof
ãŸããgprofèšäºã®äŸ¿å©ãªã¹ã¯ãªããã䜿çšããŠãããã°ã©ã ãäœåºŠãåŒã³åºããŠçµ±èšãèç©ããŸãã çµæã¯æ¬¡ã®ãšããã§ãã
% cumulative self self total time seconds seconds calls Ts/call Ts/call name 81.98 432.87 432.87 compar 18.17 528.82 95.95 print_arr 0.00 528.82 0.00 1100 0.00 0.00 form_filename 0.00 528.82 0.00 100 0.00 0.00 merge 0.00 528.82 0.00 100 0.00 0.00 save_buf 0.00 528.82 0.00 10 0.00 0.00 external_merge_sort 0.00 528.82 0.00 10 0.00 0.00 split
ã»ãšãã©ã®æéã¯ãœãŒããšåºåã«è²»ããããŸããã ãã ããgprofã¯ã·ã¹ãã ã³ãŒã«ãšI / Oã«ããã£ãæéã衚瀺ããªãããšãå¿ããªãã§ãã ããã
ããã§äœãæ¹åã§ããŸããïŒ
- å€éšãœãŒãã«ãã«ãã¹ã¬ãããšI / Oããªãã¯ãè¿œå ãã
- å¥ã®ãœãŒãã¢ã«ãŽãªãºã ã䜿çšãã
ãŠãããŒãµã«å€éšããŒãžãœãŒãã¯ãå°éã®ã¡ã¢ãªã§ããã°ããŒã¿ããœãŒãããããã®ã·ã³ãã«ãªã¢ã€ãã¢ã§ãããæ¹åãªãã§ãã£ãããšåäœããŸãã
䞊ã¹æ¿ããã«ã¹ã¿ãã€ãºãã
ãã¡ããããã«ãã¹ã¬ããã䜿çšããŠåé¢ããŠããŒãžããããšãã§ããŸãããããã¯æªãèãã§ãã ããŒã¿ã¯1ã€ã®ãããã¡ãŒã«å«ãŸããŠãããããåé¢ãã§ãŒãºã§äœ¿çšããããšã¯æå³ããããŸããã ã«ãŒãã«ãããŒã¿ãèªã¿åãæ¹æ³ã«åœ±é¿ãäžããããšãã§ããŸãã ããã«ã¯2ã€ã®æ©èœããããŸãã
- readaheadïŒLinuxã®ã¿ïŒã
- POSIX_FADV_SEQUENTIALãæå®ããposix_fadviseã
ã¡ã¢ãªç®¡çãµãã·ã¹ãã ã«ãããŒã¿ã®èªã¿åãæ¹æ³ãäŒããŸãã ãã®å Žåãèªã¿åãã¯ã·ãŒã±ã³ã·ã£ã«ã§ãããããããŒãžãã£ãã·ã¥å ã®ãã¡ã€ã«ã®å 容ã確èªãããšäŸ¿å©ã§ãã
ããŒãžãã§ãŒãºã§ã¯ããã¡ã€ã«ãåžžã«éãããéãããããããšã¯ã§ããŸãããããã¡ã€ã«ããšã«å°çšã®ã¹ããªãŒã ãäœæããŸãã åã¹ããªãŒã ã¯ãã¡ã€ã«ãéãããŸãŸã«ãããã®ãããã¡ãåããŸãã ãã£ã±ãã«ãªããšããœãŒããããŠåºåãããŸãã ãŸããå èªã¿ã¯åã¹ã¬ããã§æ©èœããŸãã
以äžã¯ãå€éšããŒãžãœãŒãã®é«åºŠãªãã«ãã¹ã¬ããããŒãžã§ã³ã§ãã ããŠãç§ãèšã£ãããã«ããã«ãã¹ã¬ããã¯è¯ãèãã§ã¯ãããŸããã ã·ã³ã°ã«ã³ã¢ããã»ã¹ã«éãã¯ãããŸããã
$ ./mt-ext-merge 500M.bin 50000000 > /dev/null 500000000 bytes sorted in 117.380000 seconds
ããã¯ããŒã¿åºåã§ãã ãããŠåºåãªãïŒ
$ ./mt-ext-merge-no-output 500M.bin 50000000 > /dev/null 500000000 bytes sorted in 91.040000 seconds
ããã§ã¯ã4ã³ã¢ãã·ã³ïŒIntel Core i7-3612QM CPU @ 2.10GHzïŒã§è©ŠããŠã¿ãŸãããã
$ ./naive 500M.bin > /dev/null 500000000 bytes sorted in 23.040499 seconds $ ./mmaped 500M.bin > /dev/null 500000000 bytes sorted in 23.542076 seconds $ ./external-merge 500M.bin 50000000 > /dev/null 500000000 bytes sorted in 39.228695 seconds $ ./mt-external-merge 500M.bin 50000000 > /dev/null 500000000 bytes sorted in 41.062793 seconds $ ./external-merge-no-output 500M.bin 50000000 > /dev/null 500000000 bytes sorted in 28.893745 seconds $ ./mt-external-merge-no-output 500M.bin 50000000 > /dev/null 500000000 bytes sorted in 28.368976 seconds : $ ./external-merge-no-output 500M.bin 5000000 > /dev/null 500000000 bytes sorted in 27.107728 seconds $ ./mt-external-merge-no-output 500M.bin 5000000 > /dev/null 500000000 bytes sorted in 28.558468 seconds
external-mergeãšmt-external-mergeã®éã«éãã¯ãããŸããã ããã¯ãªãã§ããïŒ ã¯ãããã«ãã¹ã¬ããã¯å ¥åããã³åºåã®å¶éã®åé¡ã解決ããªãããã§ãã 次ã®å Žåã«é©ããŠããŸãã
- ã¹ã¬ããã®ç¬ç«ããå®è¡
- å ¥åãªãœãŒã¹ãšåºåãªãœãŒã¹ã¯äžŠè¡ããŠåäœã§ããŸã-ããšãã°ãRAID
ã¹ã¬ããã¯çžäºã«äŸåããŠããŸããã¡ã€ã³ã¹ã¬ããã¯ããããã¡ããœãŒããããã®ãåŸ ã£ãŠããããã¡ã€ã«ãã次ã®èªã¿åããéå§ããå¿ èŠããããŸãã ãŸããã¹ããªãããžã®èªã¿åãã¯ãããã¡ã®ãœãŒããããé«éã§ãããããã»ãšãã©ã®å Žåãã¹ã¬ããã¯ã¡ã€ã³ã¹ã¬ãããçµäºãããŸã§åŸ æ©ããŸãã
ã¢ã«ãŽãªãºã ãæ¹åããä»ã®æ¹æ³ãå¿ èŠã§ãã
ç¹å¥ãªãœãŒãã¢ã«ãŽãªãºã
QuickSort以å€ã®ãã®ã䜿çšããŠã¿ãŸãããã æŽæ°ããœãŒãããŠããããšãããã£ãŠãããããããã䜿çšããå¿ èŠããããŸãã ç¹å®ã®ããŒã¿åã«äœ¿çšãããç¹å¥ãªã¢ã«ãŽãªãºã ãããã2ã€ã®ã°ã«ãŒãã«åããããšãã§ããŸãã
- æ¯èŒã䜿çšããªãã§ãã ãã
- ã¢ã¬ã€å šäœãã¡ã¢ãªã«ããŒãããå¿ èŠã¯ãããŸãã
OïŒn logïŒnïŒïŒ-QuickSortãªã©ã®ã¢ã«ãŽãªãºã ãæ¯èŒããããã®äžéãããåªããŠããŸãã ããããã¡ã¢ãªã®å¶éãããå Žåããããã®ãã¹ãŠãé©ããŠããããã§ã¯ãããŸããã ã ããç§ã¯ã«ãŠã³ããœãŒãã䜿çšããããšã«æ±ºããŸãã
ã«ãŠã³ããœãŒã
ã¹ãã¬ãããå°ããå€ãã®ããŒã¿ãããå Žåã¯ãã«ãŠã³ããœãŒãã䜿çšã§ããŸãã èãæ¹ã¯åçŽã§ããããŒã¿ãã¡ã¢ãªã«ä¿åããã®ã§ã¯ãªããã«ãŠã³ã¿ã®é åãä¿åããŸãã ããŒã¿ãé çªã«èªã¿åãã察å¿ããã«ãŠã³ã¿ãŒãå¢ãããŸãã ã¢ã«ãŽãªãºã ã®è€éãã¯ãæéãšããªã¥ãŒã ã§ç·åœ¢ã§ãããããŒã¿ã®ç¯å²ã«æ¯äŸããŸãã
åçŽãªå®è£ ã¯ã0ãNã®é åã§æ©èœããŸããæŽæ°ã¯é åã®ã€ã³ããã¯ã¹ã«å¯Ÿå¿ããŸãã ãããç§ã®ããŒãžã§ã³ã§ããããã¯ãã¥ãŒãã³ã°ãªãã§ããŸãæ©èœããŸãã 2çªç®ã®åŒæ°ã¯ãèŠçŽ å ã®ãããã¡ã®ãµã€ãºã§ãã ããã°ã©ã ã¯ãã¡ã€ã«ãã4ãã€ããèªã¿åããªãããããããã¡ãªã³ã°ã¯äœæ¥ãå€§å¹ ã«é«éåããŸãã
$ ./counting-array 500M-range.bin 1000000 > /dev/null Range is 1000000 500000000 bytes sorted in 3.240000 seconds
ãŠã°ã ã¹ã åã®ã¬ãã€ãã®ããŒã¿ã¯ã128 MiBã¡ã¢ãªãš1ã€ã®CPUã§3ç§åã§ãœãŒããããŸãã qsortãŸãã¯mmapãšæ¯èŒããŠãã ããïŒ
$ ./mmaped 500M-range.bin > /dev/null 500000000 bytes sorted in 76.150000 seconds
23åé«éïŒ
ãã ããå¶éïŒæŽæ°ïŒãŸãã¯ãããã«çžåœãããã®ïŒã®ã¿ïŒãšãããã®å°ããªé£ç¶ããééãå¿ããªãã§ãã ããã ããã·ã¥ãšãã€ããªæ€çŽ¢ã§äžè²«æ§ã®ãªãééã§ãªãã·ã§ã³ãäœæããããšããŸãããããã®ããã©ãŒãã³ã¹ã¯éåžžã«å£ã£ãŠããŸãã
ãããŠãæ°å€ã®äžææ§ãä»®å®ãããšãã«ãŠã³ã¿ãŒã¯2ã€ã®ç¶æ ã«ãããªããªã-ãããã©ããã«é¢ä¿ãªããåäžãããã«ããããšãã§ããŸãã ãã®åŸãé åãçž®å°ããŸãã ã¯ããé åã¯å¿ èŠãããŸããããããã®åœ¢åŒã§æ°å€ãæ ŒçŽã§ããŸããã€ãŸããé åã®ä»£ããã«ãã¯ãã«ããããŸãã æ°å€Nããã£ãå Žåããã¡ã€ã«ãèªã¿åã£ãŠNçªç®ã®ããããèšå®ããŸãããã®åŸããã¯ãã«ã調ã¹ãŠãããããã³ãã¯ãããŠããæ°å€ãåºåããŸãã
ããªãã¯ãŸã éçãè¶ ããããšãã§ããã®ã§ããã®ãããªæ±ºå®ã«ã¯æ éãªã¢ãããŒããå¿ èŠã§ãã ããšãã°ãæŽæ°ã®ç¯å²ïŒ2 32 ïŒãããã¹ãŠã®æ°å€ããœãŒãããã«ã¯ãåæ°å€ã«1ããããå¿ èŠã§ããããã¯4294967296ããã= 536870912ãã€ã= 512 MiBã§ãã ãŸãã128 MiBãããããŸããããããã§ã¯ååã§ã¯ãããŸããã ããããå Žåã«ãã£ãŠã¯ãå©çãèšå€§ã«ãªãããšããããŸã-Jon Bentleyã«ããProgramming Pearlsã®ãã®ããŒãã«é¢ããã¹ããŒãªãŒã§ãã
ããŒã¿ãç¥ãããšã¯éåžžã«åœ¹ç«ã¡ãŸãã
ãŸãšã
èšäºã«è²»ããã5ãæéãç§ã¯å€ãã®ããšãããŸãã-å€æ°ã®ããã°ã©ã ãããã€ãã®è¯ãã¢ã€ãã¢ãå€ãã®æªããã®ã ãããŠãããã«å€ãã®ããšãã§ããä¿®æ£ããããšãã§ããŸãã
ã¡ã¢ãªäžè¶³ã§ããŒã¿ã䞊ã¹æ¿ãããšããåçŽãªåé¡ã«ãããéåžžèããããªãå¥åŠãªç¹ããã¹ãŠæããã«ãªããŸããã
- äžè¬çãªã¢ã«ãŽãªãºã ã¯ãã¹ãŠã®åé¡ã«é©ããŠããããã§ã¯ãããŸãã
- ãããã°ãšãããã¡ã€ãªã³ã°ã¯éåžžã«äŸ¿å©ã§èŠèŠçãªãã®ã§ã
- ãã¹ãŠã®äœæ¥ãã³ã¢ã«ã·ããããªããšãI / Oãåé¡ã®é åã«ãªããŸã
- ãã«ãã¹ã¬ããã¯é床ã®äžèœè¬ã§ã¯ãããŸãã
- ããŒã¿ãšç°å¢ãç¥ã
ãœãŒããã¬ãŒãïŒ
ãã¹ã | çŽ æŽãªQuickSort | mmapãšã¯ã€ãã¯ãœãŒã | å€éšããŒãžãœãŒã | ãã«ãã¹ã¬ããå€éšããŒãžãœãŒã | ã«ãŠã³ããœãŒã |
2 MiBã«4 MiB | ã»ã°ãã©ã«ã | N / a | 0.38ç§ | 0.41ç§ | 0.01 |
128 MiBã§500 MB | ã»ã°ãã©ã«ã | 32.25ç§ | 87.14ç§ | 91.04 | 3.24 |
ããŒã¿ãç解ããããããšé£æºããç°¡åãªã¢ã«ãŽãªãºã ãéçºããŠãã ããïŒ
åç §è³æ
- Pythonã§2 MBã®ã¡ã¢ãªå ã®100äžåã®32ãããæ°ããœãŒãããŸã
- 倧ããªããŒã¿ã»ããã®å€éšãœãŒã
- ã¡ã¢ãªãµã€ãºãã倧ããããŒã¿ã®å¹æçãªäžŠã¹æ¿ã
- ã«ããå ¬éããŸãïŒãããã°ã©ãã³ã°ã®çç ãããã®æåã®èšäºïŒ
- ãã«ãã¹ã¬ãããã¡ã€ã«ã®å ¥åºå
- ããã©ãŒãã³ã¹æž¬å®ã«ããã¢ã«ãŽãªãºã ã®æ¹åãããŒã2
- 䞊åãœãŒãã¢ã«ãŽãªãºã