문제

내가 읽은 대부분의 코드는 a를 사용합니다 int 표준 오류 처리의 경우 (함수 및 그와 같은 반환 값). 그러나 나는 uint_8 컴파일러-읽기 : 대부분의 아키텍처의 대부분의 C 컴파일러-즉각적인 주소 모드를 사용하여 지침을 생성합니다. 즉, 1 바이트 정수를 명령어에 포함시킬 수 있습니까? 내가 생각하는 주요 명령은 UINT_8을 반환 유형으로 사용하여 함수 후 비교하는 것입니다.

1 바이트 유형을 도입하면 정렬 문제를 일으키기 때문에 문제에 대해 잘못 생각할 수 있습니다. 아마도 컴파일이 4 바이트로 포장하는 것을 좋아하는 이유가있을 수 있습니다. 이것이 모든 사람이 ints를 사용하는 이유 일 수 있습니다. 이것은 힙 대신 스택 관련 문제이므로 실제 오버 헤드가 없습니다.

옳은 일을하는 것은 내가 생각하는 것입니다. 그러나 논쟁을 위해 이것은 지능형 시계를위한 인기있는 저렴한 마이크로 프로세서이며 1K의 메모리로 구성되어 있지만 명령어 세트에는 다른 주소 지정 모드가 있다고 가정 해 봅시다.

토론을 약간 전문화하는 또 다른 질문 (x86)은 다음과 같습니다.

uint_32 x=func(); x==1;

그리고

uint_8 x=func(); x==1;

같은 유형? 또는 컴파일러는 두 번째 경우 8 바이트 리터럴을 생성 할 것입니다. 그렇다면 문자를 즉각적인 값으로 사용하고 리턴 된 int를 레지스터 참조로 비교 명령을 생성하는 데 사용할 수 있습니다. CMP 명령 유형을 참조하십시오..

X86 명령 세트의 또 다른 반동.

도움이 되었습니까?

해결책

다음은 다음 코드에 대해 하나의 특정 컴파일러가 수행 할 작업입니다.

extern int foo(void) ;
void bar(void)
{
        if(foo() == 31) { //error code 31
                do_something();
        } else {
                do_somehing_else();
        }
}

   0:   55                      push   %ebp
   1:   89 e5                   mov    %esp,%ebp
   3:   83 ec 08                sub    $0x8,%esp
   6:   e8 fc ff ff ff          call   7 <bar+0x7>
   b:   83 f8 1f                cmp    $0x1f,%eax
   e:   74 08                   je     18 <bar+0x18>
  10:   c9                      leave
  11:   e9 fc ff ff ff          jmp    12 <bar+0x12>
  16:   89 f6                   mov    %esi,%esi
  18:   c9                      leave
  19:   e9 fc ff ff ff          jmp    1a <bar+0x1a>

CMP에 대한 3 바이트 명령. foo ()가 숯을 반환하면 b : 3c 1f cmp $ 0x1f,%al을 얻는다.

만약 당신이 효율성을 찾고 있다면. %A1에서 물건을 비교하는 것이 %EAX와 비교하는 것보다 빠르다고 가정하지 마십시오.

다른 팁

특정 아키텍처의 다른 적분 유형 사이에는 속도 차이가 매우 작은 것일 수 있습니다. 그러나 당신은 그것에 의존 할 수없고, 다른 하드웨어로 이동하면 변경 될 수 있으며, 최신 하드웨어로 업그레이드하면 느리게 실행될 수도 있습니다.

그리고 당신이주는 예에서 x86에 대해 이야기한다면, 당신은 잘못된 가정을합니다. 즉각적인 것은 유형이어야합니다. uint8_t.

실제로 명령어에 포함 된 8 비트 즉시 즉시 유형이 있습니다. int8_t C 표기법으로 바이트, 단어, dword 및 Qwords와 함께 사용할 수 있습니다. char, short, int 그리고 long long.

따라서이 아키텍처에서는 코드 크기 나 실행 속도가 전혀 도움이되지 않습니다.

계산에 int 또는 부호없는 INT 유형을 사용해야합니다. 화합물에 대해서만 더 작은 유형을 사용합니다 (스트러크/어레이). 그 이유는 INT가 일반적으로 프로세서의 "가장 자연스러운"적분 유형으로 정의되기 때문입니다. 다른 모든 파생 유형은 올바르게 작동하기 위해 처리가 필요할 수 있습니다. 우리는 프로젝트에서 SPARC를 위해 Solaris의 GCC와 함께 8 및 16 비트 변수에 액세스하는 경우 코드에 명령을 추가했습니다. 메모리에서 더 작은 유형을로드 할 때 레지스터의 상단 부분이 올바르게 설정되었는지 확인해야했습니다 (서명 된 유형의 경우 부호 확장 또는 서명되지 않은 경우 0). 이로 인해 코드가 더 길고 레지스터에 대한 압력이 증가하여 다른 최적화가 악화되었습니다.

구체적인 예가 있습니다.

나는 구조물의 두 변수를 uint8_t로 선언하고 SPARC ASM에서 해당 코드를 얻었습니다.

    if(p->BQ > p->AQ)

번역되었습니다

ldub    [%l1+165], %o5  ! <variable>.BQ,
ldub    [%l1+166], %g5  ! <variable>.AQ,
and     %o5, 0xff, %g4  ! <variable>.BQ, <variable>.BQ
and     %g5, 0xff, %l0  ! <variable>.AQ, <variable>.AQ
cmp     %g4, %l0    ! <variable>.BQ, <variable>.AQ
bleu,a,pt %icc, .LL586  !

그리고 여기서 두 변수를 uint_t로 선언했을 때 얻은 것

lduw    [%l1+168], %g1  ! <variable>.BQ,
lduw    [%l1+172], %g4  ! <variable>.AQ,
cmp     %g1, %g4    ! <variable>.BQ, <variable>.AQ
bleu,a,pt %icc, .LL587  !

2 개의 산술 연산이 적고 2 개는 다른 것들에 대해 더 많이 등록합니다.

프로세서는 일반적으로 C에서 'int'인 자연 레지스터 크기로 작업하는 것을 좋아합니다.

예외가 있지만 존재하지 않는 문제에 대해 너무 많이 생각하고 있습니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top