ここで「w」に単純なPythonスクリプトよりも多くのシステムコールが必要なのはなぜですか?

ここで「w」に単純なPythonスクリプトよりも多くのシステムコールが必要なのはなぜですか?

深くダイビングしたいLinuxいつでも使える優れたツールstraceバージョン: 4.11)存在するUbuntu 16.04 LTS以下のように名前がついた理由が気になります。

# strace -c w

単純なシステムコール以上のものが必要です。Python文字列を10回印刷するスクリプト?

より具体的に言えば、出力は次のようになります。strace -c w

USER     TTY      FROM             LOGIN@   IDLE   JCPU   PCPU WHAT
shan     tty7     :0               13:20    3:37m  8:14   0.72s /sbin/upstart --user
% time     seconds  usecs/call     calls    errors syscall
------ ----------- ----------- --------- --------- ----------------
 61.67    0.000037           0       487         4 open
 23.33    0.000014           0       478           read
 15.00    0.000009           0       485           close
  0.00    0.000000           0         3           write
  0.00    0.000000           0       226           stat
  0.00    0.000000           0        38           fstat
  0.00    0.000000           0        27           lseek
  0.00    0.000000           0        63           mmap
  0.00    0.000000           0        31           mprotect
  0.00    0.000000           0        14           munmap
  0.00    0.000000           0         5           brk
  0.00    0.000000           0        22           rt_sigaction
  0.00    0.000000           0         1           rt_sigprocmask
  0.00    0.000000           0         1           ioctl
  0.00    0.000000           0        19        19 access
  0.00    0.000000           0        30           alarm
  0.00    0.000000           0         2           socket
  0.00    0.000000           0         2         2 connect
  0.00    0.000000           0         1           execve
  0.00    0.000000           0         1           uname
  0.00    0.000000           0        20           fcntl
  0.00    0.000000           0         2           getdents
  0.00    0.000000           0         1           getrlimit
  0.00    0.000000           0         2         2 statfs
  0.00    0.000000           0         1           arch_prctl
  0.00    0.000000           0         1           futex
  0.00    0.000000           0         1           set_tid_address
  0.00    0.000000           0         1           set_robust_list
------ ----------- ----------- --------- --------- ----------------
100.00    0.000060                  1965        27 total

~のためstrace -c /tmp/loop.py

% time     seconds  usecs/call     calls    errors syscall
------ ----------- ----------- --------- --------- ----------------
100.00    0.000160           9        18           getdents
  0.00    0.000000           0        54           read
  0.00    0.000000           0        10           write
  0.00    0.000000           0        44         2 open
  0.00    0.000000           0        45           close
  0.00    0.000000           0       108        16 stat
  0.00    0.000000           0        69           fstat
  0.00    0.000000           0        10           lstat
  0.00    0.000000           0        30         6 lseek
  0.00    0.000000           0        32           mmap
  0.00    0.000000           0        16           mprotect
  0.00    0.000000           0         1           munmap
  0.00    0.000000           0        14           brk
  0.00    0.000000           0        68           rt_sigaction
  0.00    0.000000           0         1           rt_sigprocmask
  0.00    0.000000           0        13         1 ioctl
  0.00    0.000000           0         9         9 access
  0.00    0.000000           0        10           select
  0.00    0.000000           0         3           dup
  0.00    0.000000           0         1           execve
  0.00    0.000000           0         1           fcntl
  0.00    0.000000           0         4         2 readlink
  0.00    0.000000           0         1           getrlimit
  0.00    0.000000           0         1           sysinfo
  0.00    0.000000           0         1           getuid
  0.00    0.000000           0         1           getgid
  0.00    0.000000           0         1           geteuid
  0.00    0.000000           0         1           getegid
  0.00    0.000000           0         1           sigaltstack
  0.00    0.000000           0         1           arch_prctl
  0.00    0.000000           0         1           futex
  0.00    0.000000           0         1           set_tid_address
  0.00    0.000000           0         1           set_robust_list
  0.00    0.000000           0         1           getrandom
------ ----------- ----------- --------- --------- ----------------
100.00    0.000160                   573        36 total

推理

  • w576Pythonスクリプトの呼び出しと比較すると、合計1965の呼び出しが必要です。

質問

  • この実装は具体的ですか?つまり、Pythonの代わりにC / C ++でコードを書くと、readより多くの呼び出しが発生しますか?

  • 使用しているプログラムやツールの複雑さに応じて呼び出しが増加しますか?相関関係がありますか?

  • スクリプトを実行するよりもスクリプトを実行すると、より多くのエラーが発生するのはなぜですかw

ノート

  • ここのPythonスクリプトは印刷する単純なループです。確認する文字列で10回、複雑ではありません。 (コードは含まれていません。ビール)

答え1

システムコールは言語に依存しません。アセンブリ言語でツールを簡単に作成できます。ゆっくりシステムコールを使用するのが非効率的であれば、高級言語で実装するよりも優れています。これを説明する洗練されたが簡単な例は次のとおりです。

$ strace -c perl -e 'print "A"x9999' >/dev/null
...
100.00    0.000026                   224        23 total
$ strace -c ./max >/dev/null
...
100.00    0.000430                 10000           total

./max以下のLinux用IA-64アセンブラはどこにありますか?

SECTION .text
Message: db "A"
global _start
_start:
mov r9,9999
_again:
        mov rax,1       ; sys_write
        mov rdi,1       ; stdout
        mov rsi,Message
        mov rdx,1
        syscall
        dec r9
        jnz _again
_finish:
        mov rax,60      ; sys_exit
        mov rdi,0       ; exit code
        syscall

コンパイルして

$ nasm -f elf64 -o max.o max.asm ; ld -o max max.o

プログラム〜しなければならない直接比較が有効になるように同じことを行います。

sys_read通話は一般的に使用されるツールの複雑さに応じて増加する可能性がありますが、利用(入力のインポート)sys_write(出力の解放)の後に、可能な限り実行される非常に複雑なニューラルネットワークの逆説的なケースを設計できますsys_exit。システムコールの数と「複雑さ」(おそらくコード行?)を分析し、傾向があるかどうかを調べるためにプロットを描くことができるようです。 (「unikernel」を読むと、複雑さの議論に関する情報を得ることができます。)

エラー列は、stdoutを閉じてからそれを記録するエントリを呼び出すことによって示されるように、エラーの数です。これは明らかに失敗します。

$ strace -c ./max >&-
% time     seconds  usecs/call     calls    errors syscall
------ ----------- ----------- --------- --------- ----------------
100.00    0.000427           0      9999      9999 write
  0.00    0.000000           0         1           execve
------ ----------- ----------- --------- --------- ----------------
100.00    0.000427                 10000      9999 total

関連情報