빠른 정수 유형이 다른 정수 유형보다 빠른 이유는 무엇입니까?


107

ISO / IEC 9899 : 2018 (C18)에서 7.20.1.3에 명시되어 있습니다.

7.20.1.3 가장 빠른 최소 너비 정수 유형

1 다음 유형 각각은 적어도 지정된 너비를 갖는 모든 정수 유형 중에서 작동하기 위해 일반적으로 가장 빠른 정수 유형 ( 268) 을 지정합니다.

2 typedef 이름 int_fastN_t은 최소 N의 uint_fastN_t너비를 가진 가장 빠른 부호있는 정수 유형을 지정합니다 . typedef 이름은 최소 N의 너비를 가진 가장 빠른 부호없는 정수 유형을 지정합니다.

3 다음 유형이 필요합니다.

int_fast8_t, int_fast16_t, int_fast32_t, int_fast64_t, uint_fast8_t, uint_fast16_t, uint_fast32_t,uint_fast64_t

이 양식의 다른 모든 유형은 선택 사항입니다.


268) 지정된 유형이 모든 목적을 위해 가장 빠른 것은 아닙니다. 구현이 한 유형을 다른 유형보다 선택하기위한 명확한 근거가 없다면 서명 및 너비 요구 사항을 충족시키는 정수 유형을 선택합니다.


그러나 이러한 "빠른"정수 유형이 더 빠른 이유는 설명되어 있지 않습니다.

  • 이 빠른 정수 유형이 다른 정수 유형보다 빠른 이유는 무엇입니까?

빠른 정수 유형은 C ++ 17의 헤더 파일에서도 사용할 수 있기 때문에 질문에 C ++로 태그를 지정했습니다 cstdint. 불행히도 ISO / IEC 14882 : 2017 (C ++ 17)에는 설명에 대한 섹션이 없습니다. 나는 그 부분을 질문의 본문에서 다르게 구현했다.


정보 : C에서는 헤더 파일에 선언되어 stdint.h있습니다.


24
여기서 중요한 점은 이러한 정수 유형이 분리되어 마술처럼 빠른 유형이 아니라는 것입니다. 그것들은 해당 시스템에서 해당 작업에서 가장 빠른 기존의 기존 유형에 대한 별칭입니다.
mtraceur

3
컴파일러는 특정 크기의 메모리 위치와 레지스터를로드, 저장, 마스킹 및 수정하기 위해 CPU 작업 opcode를 생성합니다. 그것이 CPU가 보는 전부입니다. 운영 체제는 그와 관련이 없습니다. 주어진 typedef를 직접 지정한 것처럼 정확하게 컴파일러가 수행하는 모든 작업입니다. ( 동작에 눈에 띄는 차이가없는 한 컴파일러가 사용자 typedef와 다르게 가능하면 더 효율적으로 내부 처리 할 수 있다고 가정 합니다.)
Peter-Reinstate Monica

1
@ RobertS-ReinstateMonica 정확하게 말하면,이 "별칭"은 단지 typedef진술 일뿐 입니다. 따라서 일반적으로 표준 라이브러리 수준에서 수행됩니다. 그들이 무엇에 물론, C 표준 풋 진짜 제한 typedef때문에 예를 들어 전형적인 구현하는 것입니다 -에 의를 32 비트 시스템에 있지만, 가상의 컴파일러 수있는 예를 들어 구현 고유 유형을 일부 공상을 다할 것을 약속 해당 유형의 변수에 대해 사례별로 가장 빠른 시스템 유형을 선택하는 최적화 기능이 라이브러리에 적합 합니다. int_fast32_ttypedefint__int_fasttypedef
mtraceur

1
@ RobertS-ReinstateMonica 그렇습니다. 바이너리를 이식성이 떨어 뜨리는 아키텍처 별 컴파일 플래그로 최대 성능 프로그램을 얻을 수 있습니다.
베드로-모니카 복원 복원

1
로버츠 - ReinstateMonica @ 그것은 대부분이 컴파일 된 플랫폼에서 효율적입니다 을 위해 , 반드시 .
HABO

답변:


152

64 비트 산술 연산 만 수행하는 CPU를 상상해보십시오. 이제 그러한 CPU에서 부호없는 8 비트 추가를 구현하는 방법을 상상해보십시오. 올바른 결과를 얻으려면 반드시 하나 이상의 작업이 필요합니다. 이러한 CPU에서 64 비트 작업은 다른 정수 너비 작업보다 빠릅니다. 이 상황에서 모두 Xint_fastY_t64 비트 유형의 별칭 일 수 있습니다.

CPU가 좁은 정수 유형에 대해 빠른 연산을 지원하므로 더 넓은 유형이 더 좁은 유형보다 빠르지 Xint_fastY_t않은 경우 모든 Y 비트를 나타내는 데 필요한 것보다 더 넓은 유형의 별명이 아닙니다.

호기심으로 일부 아키텍처에서 특정 구현 (GNU, Linux)의 크기를 확인했습니다. 동일한 아키텍처의 모든 구현에서 동일하지는 않습니다.

┌────╥───────────────────────────────────────────────────────────┐
 Y     sizeof(Xint_fastY_t) * CHAR_BIT                         
    ╟────────┬─────┬───────┬─────┬────────┬──────┬────────┬─────┤
     x86-64  x86  ARM64  ARM  MIPS64  MIPS  MSP430  AVR 
╞════╬════════╪═════╪═══════╪═════╪════════╪══════╪════════╪═════╡
 8   8       8    8      32   8       8     16      8   
 16  64      32   64     32   64      32    16      16  
 32  64      32   64     32   64      32    32      32  
 64  64      64   64     64   64      64    64      64  
└────╨────────┴─────┴───────┴─────┴────────┴──────┴────────┴─────┘

더 큰 유형의 작업은 더 빠를 수 있지만 이러한 유형은 캐시에서 더 많은 공간을 차지하므로 이러한 유형을 사용한다고해서 반드시 더 나은 성능을 얻을 수있는 것은 아닙니다. 또한 구현이 처음에 올바른 선택을했다는 것을 항상 신뢰할 수있는 것은 아닙니다. 항상 그렇듯이 최적의 결과를 얻으려면 측정이 필요합니다.


Android 사용자를위한 테이블 스크린 샷 :

위 표의 스크린 샷

(Android에는 모노 글꼴로 상자 그리기 문자가 없습니다 -ref )


의견은 긴 토론을위한 것이 아닙니다. 이 대화는 채팅 으로 이동 되었습니다 .
Samuel Liew

@RobertSsupportsMonicaCellio No. "모든 아키텍처에서 동일하지는 않음"도 사실이지만 표시된 데이터에서 즉시 분명하므로 명백한 사항을 언급 할 필요는 없습니다. 한 구현의 값만 보여 주었고 실제로 다른 구현에는 다른 선택이 있습니다. Windows에서 x86-64를 확인하십시오. 여기에 표시된 것과 다른 크기를 찾을 수 있습니다.
eerorika

@RobertSsupportsMonicaCellio 내 의견으로는,이 의견은 답변과 관련이 있으며 여기에 적합합니다. 그들이 필요하다고 느끼면 중재자가 그것들을 옮기도록하겠습니다.
eerorika

11

그들은 적어도 확실하지는 않습니다.

빠른 유형은 단순히 일반 유형의 typedef이지만이를 정의하는 방법은 구현에 달려 있습니다. 요청 된 크기 이상이어야하지만 더 클 수 있습니다.

일부 아키텍처에서는 일부 정수 유형이 다른 정수 유형보다 성능이 더 우수합니다. 예를 들어, 초기 ARM 구현에는 32 비트 워드 및 부호없는 바이트에 대한 메모리 액세스 명령어가 있었지만 하프 워드 또는 부호있는 바이트에 대한 명령어는 없었습니다. 하프 워드 및 부호있는 바이트 명령어는 나중에 추가되었지만, 여분의 인코딩 공간에 삽입해야하기 때문에 여전히 유연한 주소 지정 옵션이 없습니다. 또한 ARM의 모든 실제 데이터 처리 명령어는 단어에 대해 작동하므로 경우에 따라 정확한 결과를 제공하기 위해 계산 후 더 작은 값을 마스킹해야 할 수도 있습니다.

그러나 더 작은 값을로드 / 저장 / 처리하는 데 더 많은 명령이 필요하더라도 캐시 압력에 대한 경쟁 문제도 있습니다. 캐시 누락 수를 줄이면 값이 작을수록 성능이 더 우수 할 수 있습니다.

많은 공통 플랫폼에서 유형의 정의는 생각되지 않은 것 같습니다. 특히 최신 64 비트 플랫폼은 32 비트 정수를 잘 지원하는 경향이 있지만 "빠른"유형은 종종 이러한 플랫폼에서 불필요하게 64 비트입니다.

또한 C의 유형은 플랫폼 ABI의 일부가됩니다. 따라서 플랫폼 벤더가 벙어리 선택을 발견 한 경우에도 나중에 벙어리 선택을 변경하기가 어렵습니다.

"빠른"유형은 무시하십시오. 정수 성능이 정말로 염려된다면 사용 가능한 모든 크기로 코드를 벤치마킹하십시오.


7

빠른 유형은 다른 모든 정수 유형보다 빠르지 않습니다. 실제로 는 일부 "정상"정수 유형 과 동일 합니다 (해당 유형의 별칭 일뿐). 적어도 그 많은 비트.

각 고속 유형이 별칭 정수 유형 은 플랫폼에 따라 다릅니다 .

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.