Kapag pinabilis ng variable ng kapaligiran ang proseso ng 40 beses

Ngayon gusto naming pag-usapan ang ilan sa mga pinakabagong update sa Sherlock system [ito ay isang high-performance cluster sa Stanford University - approx. trans.], na makabuluhang nagpapabilis sa paglilista ng mga file sa mga direktoryo na may malaking bilang ng mga entry.

Hindi tulad ng mga regular na artikulo, ito ay higit pa sa ulat ng tagaloob sa kung paano namin regular na ginagawa ang Sherlock upang panatilihin itong tumatakbo sa pinakamainam para sa aming mga user. Inaasahan naming mag-publish ng higit pang mga artikulo tulad nito sa hinaharap.

Ang paglilista ng maraming mga file ay nangangailangan ng oras

Nagsimula ang lahat sa isang tanong sa teknikal na suporta mula sa isang user. Iniulat niya ang problema na ang pagpapatupad ls tumatagal ng ilang minuto sa isang direktoryo na may higit sa 15 mga entry $SCRATCH [direktoryo para sa pansamantalang mga file - tantiya. lane].

Libu-libong mga file sa isang direktoryo ay karaniwang nagdudulot ng isang pasanin sa file system at tiyak na hindi inirerekomenda. Alam ito ng gumagamit at inamin na hindi ito maganda, ngunit binanggit na ang listahan ay 1000 beses na mas mabilis sa kanyang laptop kaysa sa Sherlock. Siyempre, nasaktan kami nito. Kaya tumingin kami ng mas malalim.

Dahil mukhang mabait si ls

Tiningnan namin kung ano talaga ang ginagawa nito ls kapag naglilista ng isang direktoryo, at kung bakit tumatagal ang proseso. Sa karamihan ng mga modernong distribusyon ls sa pamamagitan ng default ito ay tumatakbo bilang ls --color=auto, dahil gusto ng lahat ang mga kulay.

Ngunit may presyo ang magagandang kulay: para sa bawat file ls dapat kumuha ng impormasyon tungkol sa uri ng file, mga pahintulot nito, mga flag, pinahabang katangian at mga katulad nito upang mapili ang naaangkop na kulay.

Ang isang simpleng solusyon sa problema ay ang ganap na huwag paganahin ang kulay sa ls, ngunit isipin ang galit ng mga gumagamit. Sa anumang pagkakataon dapat mong alisin ang output ng kulay, hindi kami mga halimaw.

Kaya tumingin kami ng mas malalim. ls mga entry ng kulay sa pamamagitan ng variable ng kapaligiran LS_COLORS, na nakatakda dircolors(1) batay sa configuration file dir_colors(5). Oo, binabasa ng executable ang configuration file upang lumikha ng environment variable, na ls pagkatapos ay ginagamit (at kung hindi mo alam ang tungkol sa mga file pinto (gawin), pagkatapos ay dir_colors ito ay gagana, Sa kabila ng lahat).

Tingnan natin nang maigi

Upang matukoy kung aling scheme ng kulay ang nagiging sanhi ng pagbagal, lumikha kami ng isang pang-eksperimentong kapaligiran:

$ mkdir $SCRATCH/dont
$ touch $SCRATCH/dont/{1..10000} # don't try this at home!
$ time ls --color=always $SCRATCH/dont | wc -l
10000

real    0m12.758s
user    0m0.104s
sys     0m0.699s

12,7 segundo para sa 10 mga file, hindi masyadong maganda.

Nga pala, kailangan natin ng bandila --color=always: kahit lumingon siya sa ls --color=autoPero ls nakakakita kapag hindi ito nakakonekta sa isang terminal (hal. sa pamamagitan ng pipe o sa pag-redirect ng output) at hindi pinapagana ang pangkulay kung nakatakda sa auto. Matalino na lalaki.

Kaya ano ang nagtatagal? Nagkatinginan kami strace:

$ strace -c ls --color=always $SCRATCH/dont | wc -l
10000
% time     seconds  usecs/call     calls    errors syscall
------ ----------- ----------- --------- --------- ----------------
 44.21    0.186617          19     10000           lstat
 42.60    0.179807          18     10000     10000 getxattr
 12.19    0.051438           5     10000           capget
  0.71    0.003002          38        80           getdents
  0.07    0.000305          10        30           mmap
  0.05    0.000217          12        18           mprotect
  0.03    0.000135          14        10           read
  0.03    0.000123          11        11           open
  0.02    0.000082           6        14           close
[...]

Wow: 10 tawag lstat(), 10 tawag getxattr() (na lahat ay nabigo dahil ang ating kapaligiran ay walang mga katangian na hinahanap ng ls), 10 na tawag capget().

Tiyak na mai-optimize ito.

Kakayahang katangian? Hindi

Sumusunod sa payo bug mula sa 10 taon na ang nakakaraan, sinubukan naming huwag paganahin ang pagsuri ng katangian mga kakayahan:

$ eval $(dircolors -b | sed s/ca=[^:]*:/ca=:/)
$ time strace -c ls --color=always $SCRATCH/dont | wc -l
10000
% time     seconds  usecs/call     calls    errors syscall
------ ----------- ----------- --------- --------- ----------------
 98.95    0.423443          42     10000           lstat
  0.78    0.003353          42        80           getdents
  0.04    0.000188          10        18           mprotect
  0.04    0.000181           6        30           mmap
  0.02    0.000085           9        10           read
  0.02    0.000084          28         3           mremap
  0.02    0.000077           7        11           open
  0.02    0.000066           5        14           close
[...]
------ ----------- ----------- --------- --------- ----------------
100.00    0.427920                 10221         6 total

real    0m8.160s
user    0m0.115s
sys     0m0.961s

Wow, hanggang 8 segundo ng acceleration! Inalis namin ang lahat ng mamahaling tawag na iyon getxattr(), at mga hamon capget() nawala din, grabe.

Ngunit mayroon pa ring mga nakakainis na tawag lstat(), Bagama't…

Ilang bulaklak ang kailangan mo?

Kaya naman, pinagmasdan naming mabuti LS_COLORS.

Una, hindi namin pinagana ang variable na ito:

$ echo $LS_COLORS
rs=0:di=01;34:ln=01;36:mh=00:pi=40;33:so=01;35:do=01;35:bd=40;33;01:cd=40;33;01:or=40;31;01:su=37;41:sg=30;43:ca=:tw=30;42:ow=34;42:st=37;44:ex=01;32:*.tar=01;31:*.tgz=01;31:*.arc=01;31:*.arj=01;31:*.taz=01;31:*.lha=01;31:*.lz4=01;31:*.lzh=01;31:*.lzma=01;31:*.tlz=01;31:*.txz=01;31:*.tzo=01;31:*.t7z=01;31:*.zip=01;31:*.z=01;31:*.Z=01;31:*.dz=01;31:*.gz=01;31:*.lrz=01;31:*.lz=01;31:*.lzo=01;31:*.xz=01;31:*.bz2=01;31:*.bz=01;31:*.tbz=01;31:*.tbz2=01;31:*.tz=01;31:*.deb=01;31:*.rpm=01;31:*.jar=01;31:*.war=01;31:*.ear=01;31:*.sar=01;31:*.rar=01;31:*.alz=01;31:*.ace=01;31:*.zoo=01;31:*.cpio=01;31:*.7z=01;31:*.rz=01;31:*.cab=01;31:*.jpg=01;35:*.jpeg=01;35:*.gif=01;35:*.bmp=01;35:*.pbm=01;35:*.pgm=01;35:*.ppm=01;35:*.tga=01;35:*.xbm=01;35:*.xpm=01;35:*.tif=01;35:*.tiff=01;35:*.png=01;35:*.svg=01;35:*.svgz=01;35:*.mng=01;35:*.pcx=01;35:*.mov=01;35:*.mpg=01;35:*.mpeg=01;35:*.m2v=01;35:*.mkv=01;35:*.webm=01;35:*.ogm=01;35:*.mp4=01;35:*.m4v=01;35:*.mp4v=01;35:*.vob=01;35:*.qt=01;35:*.nuv=01;35:*.wmv=01;35:*.asf=01;35:*.rm=01;35:*.rmvb=01;35:*.flc=01;35:*.avi=01;35:*.fli=01;35:*.flv=01;35:*.gl=01;35:*.dl=01;35:*.xcf=01;35:*.xwd=01;35:*.yuv=01;35:*.cgm=01;35:*.emf=01;35:*.axv=01;35:*.anx=01;35:*.ogv=01;35:*.ogx=01;35:*.aac=00;36:*.au=00;36:*.flac=00;36:*.mid=00;36:*.midi=00;36:*.mka=00;36:*.mp3=00;36:*.mpc=00;36:*.ogg=00;36:*.ra=00;36:*.wav=00;36:*.axa=00;36:*.oga=00;36:*.spx=00;36:*.xspf=00;36:
$ unset LS_COLORS
$ echo $LS_COLORS

$  time ls --color=always $SCRATCH/dont | wc -l
10000

real    0m13.037s
user    0m0.077s
sys     0m1.092s

Ano!?! 13 segundo pa?

Ito ay lumiliko out na kapag ang kapaligiran variable LS_COLORS isa lamang sa mga elemento nito ang hindi tinukoy o nawawala <type>=color:, ginagamit nito ang built-in na database bilang default at gumagamit pa rin ng mga kulay. Kaya kung gusto mong i-disable ang colorization para sa isang partikular na uri ng file, kailangan mong i-override ito <type>=: o <type> 00 sa file DIR_COLORS.

Pagkatapos ng maraming pagsubok at pagkakamali, pinaliit namin ang aming paghahanap hanggang dito:

EXEC 00
SETUID 00
SETGID 00
CAPABILITY 00

na nakasulat bilang

LS_COLORS='ex=00:su=00:sg=00:ca=00:'

Ang ibig sabihin nito ay: huwag kulayan ang mga file ayon sa katangian. mga kakayahan, ngunit unti-unti setuid/setgid, ni sa pamamagitan ng bandila ng executability.

Bilisan namin ls

At kung hindi mo gagawin ang alinman sa mga pagsusuring ito, pagkatapos ay tumawag lstat() mawala, at ngayon ay isang ganap na naiibang bagay:

$ export LS_COLORS='ex=00:su=00:sg=00:ca=00:'
$ time strace -c ls --color=always $SCRATCH/dont | wc -l
10000
% time     seconds  usecs/call     calls    errors syscall
------ ----------- ----------- --------- --------- ----------------
 63.02    0.002865          36        80           getdents
  8.10    0.000368          12        30           mmap
  5.72    0.000260          14        18           mprotect
  3.72    0.000169          15        11           open
  2.79    0.000127          13        10           read
[...]
------ ----------- ----------- --------- --------- ----------------
100.00    0.004546                   221         6 total

real    0m0.337s
user    0m0.032s
sys     0m0.029s

0,3 segundo sa isang listahan ng 10 mga file, isang talaan.

Pag-set up ng Sherlock

Mula 13 segundo na may mga default na setting hanggang 0,3 segundo na may maliliit na pagsasaayos LS_COLORS nangangahulugan ng 40-tiklop na acceleration dahil sa kawalan setuid / setgid at may kulay na mga executable na file. Hindi tulad ng isang malaking kawalan.

Siyempre, naka-configure na ito sa Sherlock para sa bawat user.

Ngunit kung nais mong ibalik ang pangkulay, maaari kang bumalik sa mga default na setting:

$ unset LS_COLORS

Ngunit pagkatapos ay sa mga direktoryo na may maraming mga file, siguraduhing magtimpla ng kape habang ito ay tumatakbo ls.

Pinagmulan: www.habr.com

Magdagdag ng komento