여기서 "w"에 간단한 Python 스크립트보다 더 많은 시스템 호출이 필요한 이유는 무엇입니까?

여기서 "w"에 간단한 Python 스크립트보다 더 많은 시스템 호출이 필요한 이유는 무엇입니까?

깊이 다이빙하고 싶어리눅스항상 사용할 수 있는 더 많은 훌륭한 도구strace(버전: 4.11) 존재하다우분투 16.04 LTS아래와 같이 이름이 붙은 이유가 궁금합니다.

# strace -c w

단순한 시스템 호출 이상의 것이 필요합니다.파이썬문자열을 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

관련 정보