Linux 유틸리티가 현재 시간을 얻기 위해 시스템 호출을 사용하지 않는 이유는 무엇입니까?

Linux 유틸리티가 현재 시간을 얻기 위해 시스템 호출을 사용하지 않는 이유는 무엇입니까?

우리 게스트 VM이 "해야 하는 것처럼" kvm-clock 드라이버를 사용하지 않는 이유를 정말로 알고 싶습니다. 그들은 RHEL 7.2, glibc-2.17, kern 3.10.0을 실행하고 있습니다. 및 와 같은 date프로그램은 perl -e 'print time'시스템 호출을 하지 않고 현재 시간을 가져옵니다. 이는 strace 및 ltrace로 확인되었으며 gdb syscall를 사용하고 rtdscp.

이것은 glibc 작성자의 최적화 시도입니까? 이 기능을 비활성화하고 glibc 호출이 시스템 호출을 하도록 강제할 수 있는 방법이 있습니까(LD_PRELOAD 해킹 누락)?

고쳐 쓰다2016년 10월 14일:

최신 내용을 검토했습니다.POSIX 초안, 대답의 일부는 분명합니다. CPU에 시계를 요청하는 방법이 있지만 GNU glibc는 실수로 사용자에게 이 구현을 강제합니다. 해결책은 시스템 호출을 직접 호출하는 것입니다. (쉿)

_POSIX_CPUTIME이 정의된 경우 구현은 주어진 프로세스에 대한 CPU 시간 시계를 나타내는 clock_getcpuclockid()를 호출하여 얻은 시계 ID 값을 지원해야 합니다. 구현에서는 시계 중 하나가 호출될 때 호출 프로세스의 CPU 시간 시계를 나타내는 특수 clockid_t 값 CLOCK_PROCESS_CPUTIME_ID도 지원해야 합니다.() 또는 타이머_() 기능.

clock_id사용자가 " 로 설정 하면 CLOCK_REALTIME시스템 호출을 사용해야 한다" 는 개념에 반대하는 실제 주장이 있습니까 ?

답변1

시스템 호출이 발생하지 않는 이유는 일부 Linux 시스템 호출(특히 및 시간과 관련된 호출 gettimeofday(2)) time(2)이 전달되기 때문이라고 생각합니다.가상 DSO에는 일부 시스템 호출의 최적화된 구현이 포함되어 있습니다.

"vDSO"(Virtual Dynamic Shared Object)는 커널에 의해 모든 사용자 공간 애플리케이션의 주소 공간에 자동으로 매핑되는 작은 공유 라이브러리입니다.

커널이 제공하는 일부 시스템 호출은 사용자 공간 코드에서 너무 자주 사용되므로 이러한 호출이 전체 성능을 좌우할 수 있습니다. 이는 사용자 공간을 종료하고 커널에 진입함으로써 발생하는 호출 빈도와 컨텍스트 전환 오버헤드 때문입니다.

이제 매뉴얼에는 필요한 정보가 메모리에 배치되어 프로세스가 직접 액세스할 수 있다고 언급되어 있습니다(현재 시간은 결국 비밀이 아닙니다). 나는 구체적인 구현을 알지 못하며 CPU 타임스탬프 카운터의 역할만 추측할 수 있습니다.

따라서 실제로 최적화하는 것은 glibc가 아니라 커널입니다. 설정을 통해 vdso=0비활성화할 수 있습니다.커널 명령줄, 컴파일할 수 있어야 합니다. 그러나 glibc 측에서 (적어도 라이브러리를 패치하지 않고) 비활성화할 수 있는지는 알 수 없습니다.

이에 대한 다른 많은 정보와 출처가 있습니다.SE에 관한 질문.


귀하의 질문에서 다음과 같이 말씀하셨습니다.

최신 POSIX 초안을 검토한 후 대답의 일부는 분명해졌습니다. CPU에서 시계를 요청하는 방법이 있지만 GNU glibc는 실수로 사용자에게 이 구현을 강제합니다.

나는 그것이 꽤 대담한 진술이라고 생각한다. 적어도 사용자에게 해를 끼치지 않는 한, 사용자에게 어떤 작업을 하도록 "부정하게 강요"했다는 증거는 없습니다. 현재 시스템에서 실행되는 거의 모든 Linux 프로세스는 vDSO를 사용하여 구현됩니다. 즉, vDSO가 제대로 작동하지 않으면 사람들은 매우 큰 불만을 듣게 될 것입니다. 받은 시간도 정확하다고 하더군요.

매뉴얼에서 제공한 인용문에는 clock_gettime통화가 다음에서 지원되어야 한다고 언급된 것 같습니다.clock_getcpuclockidCLOCK_REALTIME, 또는의 행동과 아무 관련이 없습니다.gettimeofday.

관련 정보