C 문자열 라이브러리를 직접 구현하려고 시도했을 때 glibc와 Linux 커널이 특정 기능을 다르게 구현한다는 것을 발견했습니다. 예를 들어,glibc 메모리 로거그리고glibc 문자열기능 속도를 높이려면 몇 가지 트릭을 사용하십시오.kernelmemchr그리고커널 strchr아니요. Linux 커널 기능이 glibc처럼 최적화되지 않은 이유는 무엇입니까?
답변1
커널은 아키텍처별 디렉토리에서 이러한 기능 중 일부의 최적화된 버전을 제공합니다.x86 구현memchr
(바라보다모든 memchr
정의, 그리고모든 strchr
정의). 찾은 버전은 대체 일반 버전입니다. 및 에 #ifndef __HAVE_ARCH_MEMCHR
대한 보호 검사를 찾아 이를 찾을 수 있습니다 .memchr
#ifndef __HAVE_ARCH_STRCHR
strchr
C 라이브러리의 최적화된 버전은 더 복잡한 코드에서 작동하는 경향이 있으므로 위의 내용은 커널이 속도를 높이기 위해 노력하지 않는 이유를 설명하지 않습니다. 커널이 이러한 기능 중 하나의 보다 최적화된 버전으로부터 이점을 얻을 수 있는 시나리오를 찾을 수 있다면 패치가 환영받을 것이라고 생각합니다(적절한 지원 증거가 있고 최적화된 기능이 여전히 이해할 수 있는 한 - 참조).이 오래된 토론은memcpy
). 그러나 나는 커널이 이러한 함수를 사용하는 것이 일반적으로 그만한 가치가 없다고 생각합니다. 예를 들어 memcpy
관련 함수는 커널의 작은 버퍼에서 사용되는 경향이 있습니다. 그리고 캐시에 맞거나 인라인될 수 있는 짧은 함수로 인한 속도 향상을 과소평가하지 마십시오.
게다가 다음과 같이나는 존재하지 않을 것이다 나는 존재하지 않을 것이다,MMX 및 SSE는 커널에서 쉽게 사용할 수 없습니다., 메모리 검색 또는 복사 기능의 많은 최적화된 버전이 이에 의존합니다.
대부분의 경우 사용되는 버전은 다음과 같습니다.컴파일러의 내장 버전그럼에도 불구하고 이들은 C 라이브러리보다 훨씬 더 최적화되어 있습니다(예: memcpy
레지스터 로드 및 저장 또는 상수 저장소로 종종 변환됨).
답변2
2006년에 Solaris에서 mkisofs
.
ISO 형식 지정 소프트웨어는 ISO-9660 디렉토리 항목 중간에 Rock Ridge 파일 이름을 포함하지 않지만(예: mkisofs
ISO-9660 디렉토리 항목 끝에는 포함합니다.) 이제 Rock Ridge 파일 이름이 널바이트로 끝나지 않는다는 것을 알아야 합니다...
어떤 경우에는 Solaris 커널의 (당시 과도하게 최적화된) 문자열 루틴이 1을 초과할 수 있었고, Rock Ridge 파일 이름이 2k 섹터의 끝에서 종료되어 4k의 경우 END가 되는 경우가 있었습니다. 커널 메모리 페이지에서 이러한 초과 액세스로 인해 불법 메모리 액세스로 인해 커널 패닉이 발생할 수 있습니다.
앞으로 이런 종류의 커널 패닉을 방지하려면 액세스 코드를 매우 보수적으로 다시 작성해야 합니다.
보시다시피 커널에 대한 안전한 코드를 작성하는 것이 때로는 훨씬 더 어렵고 이러한 코드는 단지 커널 패닉을 피하기 위해 속도가 느려질 수도 있습니다.
참고: MMU 페이지 끝에 도달하는 것이 가능하다면 링커가 세그먼트 뒤에 몇 바이트를 추가하도록 함으로써 사용자 공간 프로그램의 CPU에서 잠재적으로 예측할 수 없는 프리패치를 처리할 수 있습니다. 이는 매핑된 영역에 의존하는 커널에서는 작동하지 않습니다.