FreeBSD와 Linux: 커널 호출 규칙 성능

FreeBSD와 Linux: 커널 호출 규칙 성능

~에서int80h.org, FreeBSD 어셈블리 언어 튜토리얼

[Linux 호출] 규칙은 적어도 어셈블리 언어 프로그래밍에 관한 한 Unix 방식에 비해 큰 단점이 있습니다. 커널 호출을 할 때마다 레지스터를 푸시한 다음 팝해야 합니다. 이렇게 하면 코드가 더 커지고 느려집니다.

FreeBSD가 Linux 규칙과 "Unix 규칙"을 지원한다고 계속해서 말하세요.

FreeBSD용으로 특별히 코딩하는 경우 항상 Unix 규칙을 사용해야 합니다. 더 빠르고 전역 변수를 레지스터에 저장할 수 있으며 실행 파일에 브랜드를 지정할 필요가 없으며 Linux 에뮬레이션 패키지를 강제로 실행할 필요가 없습니다. 대상 시스템에 설치해야 합니다.

나는 리눅스 방식이 더 투박하고 느리다는 사실이 이상하다고 생각합니다. 선택지는 2가지인 것 같은데,

  • 보관해야 하는 레지스터만 저장하세요.
    • 시스템 호출로 인해 손상될 수 있는 휘발성 레지스터(내가 아는 한 ecx)
    • 또는 레지스터를 생성하기 위해 적절한 매개변수를 커널로 전송해야 합니다 syscall(아마도 eax, ecx, edx, esi, edi, ebp).
  • 커널 매개변수를 100% 스택에 저장합니다.

FreeBSD인 것 같습니다.가장 나쁜Linux 컨벤션 사례 시나리오. 내가 무엇을 놓치고 있나요? FreeBSD 규칙("Unix 방식"이라고 함)은 어떻게 더 작고 빨라질 수 있습니까?

답변1

제 생각에는 글쓴이의 관점이 정말 맞는 것 같습니다.

FreeBSD("Unix") 규칙에서는 인수가 스택에 푸시되고 시스템 호출 번호가 에 지정되며 EAX인터럽트 0x80이 호출됩니다(별도의 함수에서 호출이 예상되므로 스택에 추가 피연산자를 사용하여).

Linux i386 규칙에서는 매개변수를 적절한 레지스터에 배치하고 인터럽트 0x80을 호출합니다.

크고 느린 논쟁은 아마도 Linux 규칙에 따르면 다음과 같은 사실에서 비롯될 것입니다.방문객레지스터 사용을 처리해야 합니다. 시스템 호출에 호출자가 관심을 갖는 값이 포함된 레지스터의 매개변수가 필요한 경우 해당 매개변수를 보존해야 하므로 추가 작업이 필요합니다.C 라이브러리의 예제 보기. 이 예에서 시스템 호출에는 EAX, EBX, EDX, EDI 및 ESI의 값이 필요하지만 호출자는 EBX, EDI 및 ESI 유지에만 관심이 있으므로 해당 값을 스택에 푸시합니다. 일반적인 상황은꽤 복잡하다(그러나 그것은 또한 C와 어셈블리의 혼합을 처리하고 모든 상황에서 최상의 코드를 생성하려고 노력한 결과이기도 합니다.) 하지만 언급한 사이트의 요점인 어셈블리로 작성할 때는 그렇지 않습니다. 그게 아니더라도 큰 문제다.

제 생각에는 6개 반입니다. FreeBSD 규칙에서는 모든 경우에 스택에 푸시하고, Linux 규칙에서는 수행 중인 호출 사이트에 따라 스택(또는 다른 곳)에 푸시합니다. 모든 계산을 레지스터에서 수행할 수 있기 때문에 Linux 규칙을 사용하면 더 빠른 코드가 가능하다고 말할 수도 있습니다.struct pt_regs그러나 Linux에서는 결국 레지스터가 푸시되므로( 시스템 호출을 처리하는 C 함수에 인수를 제공하기 위해 구축된 인스턴스) Linux 측의 전체 비용이 Linux 측보다 높다는 점이 지적되었습니다 . FreeBSD 측.

그럼에도 불구하고, 시스템 호출 자체를 실행하는 데 드는 비용을 고려하면 시스템 호출과 관련된 스택 또는 레지스터 기반 코드에 관해 이야기할 때 성능에 대해 논쟁하는 것은 다소 현학적인 것처럼 보입니다. 모든 사이클 절감은 절대적인 의미에서는 확실히 좋지만 상대적인 개선 효과는 작습니다.

관련 정보