2013-11-22 1 views
0

어셈블리에 관한 몇 가지 사항을 공부하고 있으며, 필자는 x86 운영 체제에서 16 비트 용으로 컴파일 된 프로그램이 더 느리게 회전하고 x64 용으로는 32 비트 컴파일 된 프로그램이 x64에서 더 느리게 실행된다는 ...x86 운영 체제에서 16 비트 프로그램을 실행하는 것이 왜 느려 집니까?

왜 이런 일이 발생합니까? 컴퓨터 메모리와 프로세서에서 어떤 일이 발생하여 프로그램 16 비트 또는 32 비트 컴퓨터가 각각 32 비트와 64 비트로 더 느리게 회전합니까? (? 조립 작업)

+1

짧은 대답 : CPU가 최근 작성된 코드의 이점을 위해 최적화 되었기 때문에 이전의 레거시 코드를 희생해야합니다. –

답변

2

에 대해 16 비트 프로그램을, 당신은 그것에 대해 알 수 있습니다. 인텔이 16 비트에서 32 비트로 갈 때 새로운 32 비트 레지스터를 처리하도록 명령 세트를 확장해야하지만 16 비트 프로그램과 이진 호환성을 유지해야했습니다.

16 비트 레지스터를 사용하는 명령어에 적용 할 때 32 비트 레지스터를 사용하도록 지시하는 접두사 66h가 추가되었습니다. 예를 들어

는 66H로 시작 MOV의 AX, BX, 같은 16 비트 명령어, MOV의 EAX, EBX

로 변신하지만 그들은에서 필요로하기 때문에이 후, 새로운 32 개 비트 명령어에 벌금을 부과 실행을위한 최소 메모리 페치 사이클. 그런 다음 인텔은 소위 32 비트 세그먼트와 16 비트 세그먼트를 만들었습니다.

기본적으로 코드 조각은 코드 세그먼트에 있어야합니다. 80386 이전에는 모든 세그먼트가 16 비트 명령어를 사용했으며 모든 명령어는 16 비트 레지스터를 사용한다고 가정합니다.

Intel의 32 세그먼트에도 코드가 있지만 이번에는 모든 명령어가 32 비트 레지스터를 사용한다고 가정하므로 32 비트 세그먼트에서 MOV EAX, EBX의 opcode는 MOV AX의 opcode와 같습니다. , BX (16 비트 세그먼트).

이렇게하면 프로그램에서 모든 32 비트 명령어에 66h 프리픽스를 사용할 필요가 없습니다. 더 이상 벌칙이 없습니다.

하지만 32 비트 세그먼트로 결합 된 프로그램 내에서 16 비트 레지스터를 사용해야한다면 어떻게해야합니까?16 비트 레지스터를 사용하는 명령어는 접두사 66h를 사용해야합니다.

그래서 : 16 비트 레지스터를 사용하는 명령어는 16 비트 세그먼트로 접두어가 붙지 않고 32 비트 semgnt로 시작됩니다. 32 비트 레지스터를 사용하는 명령어는 32 비트 세그먼트로 접두어가 붙지 않고 16 비트 세그먼트로 시작됩니다.

이외에도 : 우리는 펜티엄 프로세서에서 시작하여 병렬로 명령을 실행하기위한 두 개의 파이프 라인을 가지고 있습니다. 이러한 파이프 라인을 사용하려면 명령어를 입력하는 명령어가 인텔 이름 인 "RISC 뉴 클루 스"에 속해야합니다. CPU 내부의 마이크로 프로그램으로는 더 이상 실행되지 않지만 유선 논리를 사용하는 명령어의 하위 집합입니다. 맞춰봐? 16 비트 레지스터를 사용하는 16 비트 세그먼트에서 실행되는 접두어가 붙은 명령어 및 코드는이 그룹에 속하지 않으므로 다른 그룹과 병렬로 실행할 수 없습니다. 접두사가 붙은 명령이 파이프 라인 중 하나에 들어가면 그 중 하나는 CPU의 성능에 영향을 미치게됩니다.

0

난 당신이 회전에 의해 무슨 뜻인지 잘 모르겠지만, 일반적으로 여기에 여러 가지 요인이있을 수 있습니다 -

  1. CPU 회사는 정말 지원의 노력에 가지 마세요 오래된 레거시 모드 및 ISA 하위 집합. x87은 좋은 예입니다. 실제로 그 정도의 수준을 요구하지 않는 것은 벡터화뿐만 아니라 성능에 중요한 작업을 위해 SSE/AVX를 사용하는 것이 좋습니다.

  2. x86 CPU 회사가 레지스터 크기를 늘릴 때마다 이전 레지스터 집합을 유지하고 더 긴 버전의 논리 이름을 추가하기 만했습니다. 호환성의 필요성 때문에 이전 연산이 동일한 레지스터에서 여전히 작동 할 수 있으므로 동일한 프로그램에서 ah/al, ax, eax 및 rax에 쓸 수 있습니다. 이러한 경우 중 일부 (즉, 8 비트/16 비트 부분)에서는 이러한 호환성으로 인해 CPU가 레지스터의 윗부분을 그대로 유지해야하며, 이렇게하면 병합 작업이 암시 적으로 발생할 수 있습니다. 감속. 더 나쁜 것은 16 비트 레지스터에 대한 각 쓰기가 이전 작업에서 남아 있던 상위 부분을 병합해야하므로 잘못된 종속성을 도입 할 수 있다는 것입니다.

는 여기를 참조하십시오 - 32 비트 시스템에서 느리게 실행 Why do most x64 instructions zero the upper part of a 32 bit register

1

"프로그램이 더 천천히 회전합니다"... 음 ... 프로그램은 "회전"하지 않지만 "실행됩니다". 당신이 비트 회전 명령에 대해 이야기하고 있다면 ... 음. 8086에는 회전 할 비트 수를 지정하는 중간 인수를 사용하는 명령어와이를 지정하는 레지스터 (일반적으로 CX/ECX)를 사용하는 명령어가 있습니다.

8086 프로세서는 중간 인수에 대해 1 이외의 다른 값을 허용하지 않습니다 (단, CX/ECX의 값은 1보다 클 수 있습니다). 80386 이상의 프로세서는 다른 값을 중간 피연산자로 사용할 수 있습니다. 게다가 32 비트 프로세서는 회전 양을 지정하는 피연산자의 하위 5 비트만을 사용하기 때문에 연산은 31을 초과하지 않습니다 (31 비트가 넘는 32 비트 레지스터를 회전시키는 것은 의미가 없습니다). 8086 프로세서는이 제한을 두지 않으므로 작업에 더 많은 시간을 소비합니다.

"더 천천히 회전"하여 책이 의미하는 바를 모르겠다. 회전 작업은 파이프 라인 중 하나에서만 수행 할 수 있으며 둘 다 수행 할 수는 없으므로 두 개의 연속 회전 명령을 페어링 할 수 없습니다.

관련 문제