표준위원회가 관심을 갖는 이국적인 아키텍처


154

C 및 C ++ 표준은 다른 특성을 가진 아키텍처가있는 경우 표준 준수 컴파일러를 작성하는 것이 매우 어렵거나 불가능하기 때문에 언어 구현 정의의 여러 측면을 남겨둔다는 것을 알고 있습니다.

나는 40 년 전에 모든 컴퓨터가 고유 한 사양을 가지고 있다는 것을 알고 있습니다. 그러나 현재 사용되는 아키텍처는 다음과 같습니다.

  • CHAR_BIT != 8
  • signed 2의 보수가 아닙니다 (Java에 문제가 있다고 들었습니다).
  • 부동 소수점은 IEEE 754와 호환되지 않습니다 (편집 : "IEEE 754 이진 인코딩이 아님"을 의미 함).

내가 묻는 이유는 사람들에게 C ++이 고정 크기 유형 과 같은 다른 저수준 측면을 요구하지 않는 것이 좋다고 종종 설명하기 때문 입니다. '다른 언어'와 달리 코드를 올바르게 사용할 때 코드를 이식 가능하게 만들기 때문에 좋습니다 (편집 : 부호 + 크기 아키텍처에 대한 2의 보수 산술과 같이 기계의 저수준 측면을 에뮬레이션하지 않고도 더 많은 아키텍처로 이식 될 수 있기 때문에) . 그러나 특정 아키텍처를 직접 가리킬 수 없다는 것은 기분이 좋지 않습니다.

질문은 무엇입니까? 위의 속성을 나타내는 아키텍처는 무엇입니까?

uint*_ts는 선택 사항입니다.


9
나는 당신이 그것을 뒤로 가지고 있다고 생각합니다. 예를 들어 C ++이 부호있는 정수를 보완하면 C ++ 코드를 더 이식성있게 만들 수 있습니다. C ++ 표준위원회가 왜 이것을 요구하지 않는지에 대한 질문은 또 다른 문제입니다. 특히, 당신이 말한 것에도 불구하고 비표준 아키텍처 용 컴파일러를 작성하는 것은 불가능 하지 않으므로 플랫폼에서 직접 지원하지 않는 경우에도 항상 8 비트 문자 또는 2를 보완하는 산술을 시뮬레이션 할 수 있습니다.
john

8
@ john : 그렇다면 비표준 준수 컴파일러는 일치하는 코드보다 빠른 코드를 생성합니다. 그리고 나는 그것이 어떻게 코드를 더 이식성이있게 만드는지 알지 못합니다.
Yakov Galka

4
표준의 진정한 이유는 이상적인 솔루션이기 때문이 아니라고 확신합니다. 그러나 표준을 작성할 때 많은 C 및 C ++ 컴파일러가 이미 존재하고 표준위원회가 기존 컴파일러를 거부하고 싶지 않았기 때문입니다.
john

4
@ john : C ++ 표준을 만들 때 "컴파일러 작성자가 더 쉽게 만드는 것"이 ​​우선 순위라는 것은 의심의 여지가 있습니다. 이 언어는 컴파일러 작성자도 쉽게 만들지 않습니다). 그러나 성능, 광범위한 플랫폼 지원 및 이전 버전과의 호환성이 매우 중요합니다. 언급 한 제한 사항이 표준에 추가되면이 세 가지 문제가 모두 발생합니다.
샌더 드 다이 커

5
컴파일러가 아니라 하드웨어에 관한 것입니다. C ++는 하드웨어 기능을 직접 사용할 수 있도록 일부를 지정하지 않은 상태로 둡니다. 휴대 전화 앱은 메인 프레임에서 실행되지 않으므로 코드와 호환되는 이식성이 없습니다.
보 퍼슨

답변:


114

이것 좀 봐

Unisys ClearPath Dorado 서버

아직 모든 Univac 소프트웨어를 마이그레이션하지 않은 사람들에게 역 호환성을 제공합니다.

키 포인트:

  • 36 비트 단어
  • CHAR_BIT == 9
  • 보완하다
  • 72 비트 비 IEEE 부동 소수점
  • 코드와 데이터를위한 별도의 주소 공간
  • 단어 주소
  • 전용 스택 포인터가 없음

그들이 비록 C ++ 컴파일러를 제공하고 있는지 알고 있지만하지 마십시오 있었다 .


그리고 현재 C 매뉴얼의 최신 버전에 대한 링크가 나타났습니다.

Unisys C 컴파일러 프로그래밍 참조 매뉴얼

4.5 절에는 9, 18, 36 및 72 비트의 데이터 유형 표가 있습니다.

USC C 컴파일러에서 데이터 유형의 크기 및 범위


13
그 아키텍처에서 void *가 사용하기에는 지옥 같은 것 같아요.
luiscubal

13
@ybungalobill - 저는 믿습니다 char*void*같은 크기, 다른 포인터를 보유 할 충분한해야합니다. 나머지는 구현에 달려 있습니다.
보 퍼슨

22
@ybungalobill : 오래된 Win16 컴파일러에서 일반 포인터는 포인터 근처에 있었고 16 비트 오프셋 sizeof(int*) == 2만 포함했지만 먼 포인터에도 16 비트 선택기가 sizeof(void*) == 4있습니다.
아담 로젠 필드

10
C ++ 컴파일러에 대한 온라인 설명서가 있거나 사용되었습니다. 또한 이것이 Unisys 메인 프레임 아키텍처 중 하나 일뿐입니다. 다른 하나는 48 비트 부호있는 크기 태그가있는 아키텍처입니다 (C ++이 아닌 C 매뉴얼 만 찾았습니다). 나머지 부분에 관해서 : 나는 sizeof(int*) != sizeof(char*)여기에서 생각하지 않습니다 : 둘 다 36 비트입니다. 그러나의 바이트 선택기 char*는 상위 비트에 있으며에서 무시됩니다 int*. (그러나`sizeof (char *)> sizeof (int *) 인 다른 머신을 사용했습니다.)
James Kanze

16
@Adam Rosenfield MS / DOS 16 비트 컴파일러에서는 "모드"가 다르며 데이터 포인터의 크기가 함수 포인터의 크기와 반드시 같을 필요는 없었습니다. 그러나 적어도 내가 사용했던 것에서 모든 데이터 포인터 (포함 void*)는 항상 같은 크기였습니다. (물론, 더 작을 수도 있기 void*때문에 함수 포인터를로 변환 할 수 없었 void*습니다. 그러나 표준에 따르면 오늘도 그렇게 할 수 없습니다.)
James Kanze

51

메인 프레임에 대한 가정은 없습니다. 우선 IEEE 754를 사용하는 메인 프레임에 대해 잘 모르겠습니다. IBM은 기본 16 부동 소수점을 사용하고 두 Unisys 메인 프레임은 모두 8을 사용합니다. Unisys 시스템은 다른 여러 측면에서 약간 특별합니다. Bo는 2200을 언급했습니다. MPS 아키텍처는 48 비트 태그가 붙은 단어입니다. (단어가 포인터인지 여부는 워드의 비트에 따라 달라집니다.) 그리고 숫자 표현은 부동 소수점과 정수 산술 사이에 실질적인 구분이 없도록 설계되었습니다. 부동 소수점은 밑이 8입니다. 정규화가 필요하지 않으며 내가 본 다른 모든 부동 소수점과 달리 소수점을 왼쪽이 아닌 가수의 오른쪽에 소수점을 넣고 지수에 부호가있는 크기를 사용합니다 (가수에 추가). 그 결과 정수 부동 소수점 값은 부호있는 크기 정수와 정확히 동일한 비트 표현을 갖거나 가질 수 있습니다. 부동 소수점 산술 명령어는 없습니다. 두 값의 지수가 모두 0 인 경우 명령어는 정수 산술을 수행하고, 그렇지 않으면 부동 소수점 산술을 수행합니다. (아키텍처의 태깅 철학이 계속됨)int 48 비트를 차지할 수 있으며 그 중 8은 0이어야합니다. 그렇지 않으면 값이 정수로 취급되지 않습니다.


4
IBM 메인 프레임 (z / 아키텍처)은 IEE754 부동 소수점을 지원합니다.
Nikita Nemkin 2016 년

1
참고하시기 바랍니다 볼 이 트위터 코멘트
Shafik Yaghmour

6
@Nikita-그들은 지금한다 . 처음에는 Java를 지원하기위한 (비싼) 애드온이었습니다.
Bo Persson


42

부동 소수점 구현에서는 전체 IEEE 754 준수가 거의 없습니다. 그리고 이와 관련하여 사양을 약화 시키면 많은 최적화가 가능합니다.

예를 들어, subnorm은 x87과 SSE의 차이점을 지원합니다.

소스 코드에서 분리 된 곱셈과 덧셈의 융합과 같은 최적화는 결과도 약간 변경하지만 일부 아키텍처에서는 최적화가 좋습니다.

또는 x86 엄격한 IEEE 준수에서는 내부 80 비트 부동 소수점 대신 지정된 부동 소수점 유형을 사용하도록 부동 소수점 레지스터와 일반 메모리간에 특정 플래그를 설정하거나 추가 전송이 필요할 수 있습니다.

또한 일부 플랫폼에는 하드웨어 플로트가 전혀 없으므로 소프트웨어로 에뮬레이션해야합니다. IEEE 754의 일부 요구 사항은 소프트웨어로 구현하는 데 비용이 많이들 수 있습니다. 특히 반올림 규칙이 문제가 될 수 있습니다.

제 결론은 항상 엄격한 IEEE 준수를 보장하고 싶지는 않은 상황에 대비하기 위해 이국적인 아키텍처가 필요하지 않다는 것입니다. 이러한 이유로 엄격한 IEEE 준수를 보장하는 프로그래밍 언어는 거의 없었습니다.


7
또 다른 "이국적인"하드웨어 세트는 부동 소수점 형식이 IEEE 표준보다 먼저 사용되는 IBM 메인 프레임입니다. Java와 달리 C ++은 여전히 ​​기존 하드웨어를 사용할 수 있습니다.
보 퍼슨

5
IEEE 754는 GPU에서 완전히 지원되지 않습니다.
kerem

3
IEEE 754에 대한 엄격한 준수 부족은 일부 귀찮지 만 OP가 실제로 관심을 갖는 문제의 범위에 있다고 생각하지 않습니다.
Omnifarious

3
@Matthieu이 태그에도 "C"라는 태그가 붙어 있으므로 C 컴파일러의 변덕에 따라 부동 소수점 프로그램이 메모리에 유출 된 80 비트 부동 소수점 레지스터로 취할 수있는 모든 값을 알려주는 C 분석기를 언급해야합니다.blog.frama-c.com/index.php?post/2011/03/03/cosine-for-real
Pascal Cuoq

2
@MatthieuM .: 너무 나쁘다 ISO / ANSI에서 가변 변수가 부동 소수점 및 정수 인수에 대한 최소 / 최대 크기를 지정할 수 없었습니다. 그들이 가지고 있다면, 80 비트 long double는 유용하고 오래 지속되는 유형 일 수 있습니다. 왜냐하면 그것의 진짜 문제는와 함께 잘못 작동한다는 것이기 때문입니다 printf. 확장 된 double이 선행 1을 저장한다는 사실은 비 FPU 시스템에서 계산 속도를 명시 적으로 높이고 다른 유형과의 변환 이외의 모든 컨텍스트에서 비정규를 특수하게 처리 할 필요가 없다는 사실입니다. 너무 나쁜 C는 printf모든 것을 망쳤다.
슈퍼 캣

40

내가 찾은 일부 시스템 목록이 링크 어디 CHAR_BIT != 8. 그들은 포함

일부 TI DSP는 CHAR_BIT == 16

BlueCore-5 칩 (Cambridge Silicon Radio의 Bluetooth 칩) CHAR_BIT == 16.

물론 스택 오버플로에 대한 질문 이 있습니다 .8 비트 문자 이외의 플랫폼이있는 플랫폼

비 보완 시스템에 대해서는 comp.lang.c ++. moderated 에 대한 흥미로운 내용이 있습니다. 요약 : 보완 또는 부호 및 크기 표현을 가진 플랫폼이 있습니다.


5
Analog Devices의 32 비트 SHARC DSP에는 CHAR_BIT=32TMS32F28xx의 Texas Instruments DSP가 CHAR_BIT=16있습니다. PDP-10 용 GCC 3.2는 다음과 같습니다 CHAR_BIT=9. S / 360에는 8 비트가 아닌 문자가있을 수 있습니다.
osgx

1
나는 여전히 '2가 아닌 보완'아키텍처의 예를 원합니다. 특히 CHAR_BITS부분 복제본 이므로 발생했습니다 .
Yakov Galka

TI DSP는 16 비트 문자 만 가지고있다 (구현자가 그것을 선택했기 때문에 약간 더 많은 노력이 필요하지만, IIRC는 터무니없이 힘들지는 않다. 아마도 기본 컴파일러의 코드 겐 스캐 폴딩에 "홀"일 것이다) . 깊은 건축 이유가 아닙니다. C 코드는 추상 머신에서 작동합니다. 가지고있는 것이 16 비트 INT 인 경우 각각 2 개의 문자를 저장하고 틈새 최적화에 읽기-수정-쓰기 병합을 추가하십시오 (최소한). 물론 그것은 더 많은 일이지만, 그들이 보이지 않는 곳에서 그러한 이상한 유형을 다루는 사람들이 얼마나 많은 일을하는지 살펴보십시오. 왝.
Monica Monica 복원

24

VAX 시스템이 여전히 사용되고 있다고 확신합니다. IEEE 부동 소수점을 지원하지 않습니다. 그들은 자신의 형식을 사용합니다. Alpha는 VAX 및 IEEE 부동 소수점 형식을 모두 지원합니다.

최신 Cray 시스템은 IEEE를 사용하지만 T90과 같은 Cray 벡터 시스템도 자체 부동 소수점 형식을 갖습니다. (내가 사용한 T90은 몇 년 전에 사용이 중단되었으므로 아직 활발하게 사용중인 제품인지는 모르겠습니다.)

T90에는 포인터와 정수에 대한 흥미로운 표현이 있습니다. 기본 주소는 64 비트 단어 만 가리킬 수 있습니다. C 및 C ++ 컴파일러는 CHAR_BIT == 8 (유닉스의 풍미 인 Unicos를 실행하고 다른 시스템과 상호 운용해야했기 때문에 필요함)을 가졌지 만 기본 주소는 64 비트 단어 만 가리킬 수있었습니다. 모든 바이트 레벨 연산은 컴파일러에 의해 합성되고 워드의 상위 3 비트에 바이트 오프셋이 저장 void*되거나 char*저장됩니다. 그리고 일부 정수 유형에는 패딩 비트가 있다고 생각합니다.

IBM 메인 프레임이 또 다른 예입니다.

반면에 이러한 특정 시스템 은 언어 표준의 변경을 반드시 배제 할 필요는 없습니다 . Cray는 C 컴파일러를 C99로 업그레이드하는 데 특별한 관심을 보이지 않았다. 아마도 C ++ 컴파일러에도 같은 내용이 적용됩니다. CHAR_BIT == 8, 전체 의미가 아닌 경우 IEEE 형식 부동 소수점, 부호있는 정수에 대한 패딩 비트가없는 2의 보수 요구와 같은 호스팅 된 구현에 대한 요구 사항을 강화하는 것이 합리적 일 있습니다. 오래된 시스템은 이전 언어 표준을 계속 지원할 수 있었으며 (C99가 나왔을 때 C90은 죽지 않았습니다) DSP와 같은 독립 실행 형 구현 (임베디드 시스템)에 대한 요구 사항이 느려질 수 있습니다.

반면에, 미래 시스템이 오늘날 이국적으로 여겨 질 수있는 일을해야 할 이유가있을 수 있습니다.


6
지나치게 엄격한 표준이 어떻게 혁신을 방해하는지에 대한 좋은 지적. 우리가 삼원 상태를 갖는 양자 (또는 유기) 컴퓨터를 얻을 때, unsigned정수형에 대한 모듈로 산술 요구 사항 은 큰 고통이 될 것이며 부호있는 산술은 괜찮을 것입니다.
벤 Voigt

@BenVoigt 왜 부호없는 산술이 고통 스럽습니까? 해당 컴퓨터에서 모듈로 3 ^ n 가산기가 가능하지 않습니까?
phuclv

2
@ LưuVĩnhPhúc : 하드웨어 모듈이 모듈로 3 ** n을 수행하는 것으로 정확히 말하면, 모듈로 2 ** n으로 정의 된 C ++ 부호없는 유형을 제공하는 것은 어려울 것입니다.
Ben Voigt

2
독점 아키텍처를 갖춘 특수 임베디드 시스템을 대상으로하는 크로스 컴파일러의 호스트로 여전히 VAX 11/780을 사용하고 있다는 것을 알고 있습니다. 특정 VAX를 유지하기 위해 관리인은 여분의 박물관에 접근하고 있습니다.
Peter

2
@Keith-기술적으로 유일한 장애물은 대상 임베디드 시스템이 매우 중요하기 때문에 규제 요구 사항을 충족시키는 증거를 제공하는 프로세스를 거치는 것입니다. 그러나 지금까지 극복 할 수 없었던 많은 비 기술적 장애물 (조직 정치 등)이 있습니다. 현재 호스트를 업데이트하는 것보다 박물관을 습격하는 것이 더 쉽습니다.
Peter

16

CHAR_BITS

gcc 소스 코드 에 따르면 :

CHAR_BIT16에 대한 비트로 1750a는 , dsp16xx 아키텍처.
CHAR_BIT24에 대한 비트로 dsp56k의 구조.
CHAR_BIT32에 대한 비트로 c4x 구조.

다음을 수행하여 더 쉽게 찾을 수 있습니다.

find $GCC_SOURCE_TREE -type f | xargs grep "#define CHAR_TYPE_SIZE"

또는

find $GCC_SOURCE_TREE -type f | xargs grep "#define BITS_PER_UNIT"

경우는 CHAR_TYPE_SIZE적절하게 정의된다.

IEEE 754 준수

대상 아키텍처가 부동 소수점 명령어를 지원하지 않는 경우 gcc 는 소프트웨어 폴백 스위치가 기본적으로 표준 호환이 아닌 것을 생성 할 수 있습니다. 특별한 옵션 ( -funsafe-math-optimizations마법사도 0의 부호 보존을 비활성화) 과 같은 특수 옵션을 사용할 수 있습니다.


3
OP가 널리 사용되는 컴파일러의 소스를 보도록 지시하기 만했다. 이것이이 경우 RFTM의 정의이므로 사람들이 가장 먼저 찾는 곳이되어야합니다.
underscore_d

9

IEEE 754 이진 표현은 최근까지 GPU에서 흔하지 않았습니다 . GPU 부동 소수점 편집증을 참조하십시오 .

편집 : GPU 부동 소수점이 그래픽과 관련이없는 일반적인 컴퓨터 프로그래밍과 관련이 있는지에 대한 의견이 제기되었습니다. 당근 빠따 지! 오늘날 산업적으로 계산 된 대부분의 고성능 작업은 GPU에서 수행됩니다. 이 목록에는 AI, 데이터 마이닝, 신경망, 물리적 시뮬레이션, 일기 예보 등이 포함됩니다. 주석의 링크 중 하나는 이유를 보여줍니다 . GPU의 소수 자릿수 부동 소수점 이점.

내가 추가하고 싶은 또 다른 것은 OP 질문과 관련이 있습니다 .10-15 년 전 사람들이 GPU 부동 소수점이 IEEE가 아니고 오늘날의 OpenCL 또는 CUDA와 같은 API가 없어서 GPU를 프로그래밍하지 않았을 때 사람들은 무엇을 했습니까? 초기 GPU 컴퓨팅 개척자들은 API없이 GPU프로그래밍 하여 관리 할 수있었습니다 . 나는 회사에서 그들 중 하나를 만났다. 그가 한 일은 다음과 같습니다. 그는 자신이 작업 한 값을 나타내는 픽셀로 이미지로 계산하는 데 필요한 데이터를 인코딩 한 다음 OpenGL을 사용하여 필요한 작업을 수행했습니다 (예 : "가우시안 블러"와 같이 정규 분포의 회선을 나타냅니다. , 결과 이미지를 다시 결과 배열로 디코딩했습니다. 그리고 이것은 여전히 ​​CPU를 사용하는 것보다 빠릅니다!

NVidia는 내부 데이터 바이너리를 IEEE와 호환 가능하게하고 이미지 조작보다는 계산에 중점을 둔 API를 도입하게되었습니다.


GPU는 어떤 관련이 있습니까? (a)이 페이지는 매우 오래된 것 같습니다 . (b) 오늘까지는 C에서 GPU를 프로그래밍 할 수 없습니다. 따라서 원하는 경우 컴파일러를 작성할 수도 없습니다.
Yakov Galka

1
@ybungalobill은 반복 작업을 GPU로 오프로드 하는 것이 현재 대규모 계산에 선호되는 방법입니다 . 사실, 저는 현재 C ++로 개발 중입니다. 다행히도 IEEE 754 호환 이진 플로트 표현이 있는 NVidia CUDA GPU 에서만 작동 합니다.
Michael

나는 GPU가 GP 계산에 사용되지 않는다고 말하지 않습니다. 구문 유사성에도 불구하고 C로 커널을 실제로 프로그래밍하지는 않는다고 말했습니다. int f(int n) { return n <= 1 ? 1 : n * f(n-1); }CUDA에서 실행할 수 있습니까 ? 그렇다면 GPU 가이 질문과 관련이 없습니다 (C 및 C ++위원회에 대해 묻습니다).
Yakov Galka

6
@ybungalobill : 그것에 대한 몇 가지 대답. 먼저 CUDA는 C, C ++ 및 Fortran을 지원 합니다. 일반적인 8 스레드 CPU에 비해 ​​2048 스레드 GPU의 엄청난 성능 이점에 대해서는 동일한 링크를 참조하십시오. 둘째, CUDA 5.0까지 CUDA 프로그래밍 모델 재귀 ( "동적 병렬 처리"라고 함)에 대한 적절한 지원 부족을 포함하여 해당 언어의 하위 집합 (대부분의 언어) 만 지원됩니다. 셋째, 재귀는 일반적으로 루프로 대체 될 수 있으며, 이는 다중 스레드 성능에 필요합니다.
Michael
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.