MSVS가 +0을 최적화하지 않는 이유는 무엇입니까?
이 질문은 매우 흥미로운 현상을 보여줍니다. 탈규격화된 플로트는 코드를 몇 배 이상 느리게 만듭니다.
그 행동은 인정된 답변에 잘 설명되어 있다.다만, 현재 153표 상승한 코멘트가 있습니다.다음 사항에 대해서는 만족스러운 답변을 찾을 수 없습니다.
이 경우 컴파일러는 +/- 0을 삭제하지 않는 이유는 무엇입니까?– 마이클 도건
사이드 노트:나는 0f가 정확히 표현되어야 한다고 생각하지만(더 나아가 이진수 표현은 모두 0이어야 함), c11 표준에서는 그러한 주장을 찾을 수 없다.이를 입증하는 인용문이나 이 주장을 반박하는 논거가 가장 환영할 것입니다.어쨌든 마이클의 질문이 여기서 가장 중요한 질문입니다.
실장에서는, 0 및 부동 소수점 번호 이외의 값(인피니티나 NaN 등)에 부호를 부여하거나 부호 없는 채로 둘 수 있습니다.
부동소수점 양의 0은 ID 연산이 아니기 때문에 컴파일러는 이를 제거할 수 없습니다.IEEE 754 규칙에 따르면 -0에 +0을 더한 결과는 -0이 아니라 +0입니다.
컴파일러는 +0의 감산 또는 -0의 덧셈을 제거할 수 있습니다.이는 아이덴티티 연산이기 때문입니다.
예를 들어, 이것을 컴파일 하는 경우:
double foo(double x) { return x + 0.; }
를 사용하여 Apple GNU C 4.2.1 을 실행합니다.-O3
인텔 Mac의 어셈블리 코드에는, 다음과 같은 것이 있습니다.addsd LC0(%rip), %xmm0
. 컴파일 할 때:
double foo(double x) { return x - 0.; }
추가 명령은 없습니다. 어셈블리는 입력만 반환합니다.
따라서 원래 질문의 코드에는 다음 문장에 대한 추가 지침이 포함되어 있을 수 있습니다.
y[i] = y[i] + 0;
단, 이 설명에 대한 지침은 포함되어 있지 않습니다.
y[i] = y[i] - 0;
그러나, 첫 번째 문장은 정규 이하의 값을 갖는 산술과 관련되었다.y[i]
그래서 프로그램의 속도를 늦추기에 충분했다.
0 상수가 아닙니다.0.0f
정규화 해제된 값은 루프의 반복마다0에 가까워지는 값입니다.0에 가까워질수록 표현하기 위한 정밀도가 높아지기 때문에 정규화가 해제됩니다.첫 번째 질문에서 이것들은y[i]
가치.
코드의 느린 버전과 빠른 버전의 중요한 차이점은 다음과 같습니다.y[i] = y[i] + 0.1f;
이 라인이 실행되면 플로트의 추가 정밀도가 상실되고 그 정밀도를 나타내기 위해 필요한 정규화가 필요 없게 됩니다. 후, 「」의 .y[i]
탈정규화되지 않았기 때문에 빠른 상태를 유지할 수 있습니다.
'여유도'를 때 의 정밀도가 거죠?0.1f
부동 소수점 숫자는 유효 자릿수밖에 없기 때문입니다. 하면, 그 다음에, 「합니다」라고 됩니다.0.00001 = 1e-5
, , , , 입니다.0.00001 + 0.1 = 0.1
형식의에서는 float에 0.10001
.
언급URL : https://stackoverflow.com/questions/16477037/why-does-msvs-not-optimize-away-0
'source' 카테고리의 다른 글
Hadoop "플랫폼에 네이티브 하둡 라이브러리를 로드할 수 없습니다" 경고 (0) | 2022.08.18 |
---|---|
날짜 문자열을 java.util로 구문 분석할 때 패턴 문자 'T'가 잘못되었습니다.날짜. (0) | 2022.08.18 |
vueJ 및 웹 팩과 함께 서드파티 jquery 라이브러리 사용 (0) | 2022.08.18 |
Linux 커널 패닉을 읽고 이해하고 분석하고 디버깅하는 방법 (0) | 2022.08.18 |
스토어 디스패치 기능이 있는 vue-test-utils 및 jest를 사용하여 컴포넌트에 Vue 메서드의 Vue 테스트 케이스를 작성하는 방법 (0) | 2022.08.18 |