이 StackOverflow 기사에는 다음이 있습니다.,
일부 환경에서는 특정 명령어나 특정 레지스터 사용에 제한이 있습니다. 예를 들어,Linux 커널에서는 SSE/AVX 또는 FP 레지스터가 일반적으로 허용되지 않습니다.따라서 대부분의 최적화된 memcpy 변형은 SSE 또는 AVX 레지스터에 의존하고 x86에서 일반 mov 기반 64비트 복사본을 사용하기 때문에 사용할 수 없습니다. 이러한 플랫폼의 경우 memcpy 최적화로 인한 대부분의 성능 이점은 SIMD 코드의 제한을 깨지 않고 rep movsb를 사용하여 얻을 수 있습니다.
x86_64 커널이 SSE/AVX를 사용할 수 없는 이유는 무엇입니까? 속도가 빨라진다면 memcopy()
허용해야 할 것 같습니다. 이 댓글을 보니 Intel Assembly를 막 배웠는데 SEE/AVX를 구체적으로 배우고 싶었습니다.
특히 Linux 커널의 SSE/MME 및 AVX 최적화에 관심이 있습니다.
답변1
~처럼자일스FPU가 사용되는 곳마다 커널은 상태 저장 및 복원을 지원해야 한다고 언급했습니다. 사용자 공간은 FPU를 사용할 수 있으므로 어떠한 경우에도 컨텍스트 전환에서 처리해야 합니다(즉, 현재 CPU가 한 스레드에서 다른 스레드로 전환될 때) - 적어도 이전에 실행 중인 스레드가 FPU를 사용하는 경우. 그렇다면 이를 커널로 확장해 보는 것은 어떨까요?
커널에서 FPU를 사용하지 않는 데는 여러 가지 이유가 있습니다.
- 이식성 관점에서 일부 아키텍처는 커널에서 FPU 사용을 전혀 지원하지 않으므로 범용 코드는 FPU에 의존할 수 없습니다.
- FPU 상태를 저장하고 복원하는 데 비용이 많이 들고 특정 구현 관련 제약이 발생합니다(특히 x86 Linux에서 선점을 신중하게 고려해야 함).
커널이 FPU를 사용하지 않도록 하는 것은 사용자 공간에 대한 비용을 줄이는 것을 의미합니다. FPU 상태는 컨텍스트 전환 후에만 복원하면 됩니다.사용자 공간으로 돌아올 때(컨텍스트 전환 직후와 반대) 모든 경우에 적용되는 것은 아닙니다(관련 스레드가 실제로 FPU를 사용하는 경우에만 해당).
그것예그러나 커널의 x86 특정 코드에서 FPU(및 MMX/SSE/AVX)를 사용할 수 있으며 이점이 비용보다 더 큽니다. 따라서 결국 암호화 코드 및 RAID6에서 사용됩니다.Linus가 보낸 이메일자세한 내용을 제공하세요. FPU를 사용하려면 kernel_fpu_begin
모든 FPU를 와 사이에 코드로 묶어서 kernel_fpu_end
결함이 발생하거나 절전 모드가 발생하지 않는지 확인해야 합니다. 바라보다arch/x86/include/asm/fpu/api.h
그리고arch/x86/kernel/fpu/core.c
더 알아보기.
의 경우 memcpy
성능 향상은 FPU 사용 비용을 초과하지 않습니다.
(x86은 상당히 복잡한 FPU 아키텍처를 가지고 있지만 운영 체제가 FPU를 공유할 수 있도록 하는 데 필요한 모든 기능을 제공합니다. FPU 명령이 실행될 때마다 트랩하여 FPU를 전혀 사용하지 않는 프로세스에 대해 커널을 최적화할 수 있습니다. CPU와 FPU 상태가 다를 수 있는 경우 지시할 수 FSAVE
있으며 FPU 상태를 저장하고 복원하는 지침도 제공하며 FPU 버전 FXSAVE
에 따라 XSAVE
이는 8086 설계의 측면일 수 있습니다.가장 예지력이 있는.)