source

MSVS가 +0을 최적화하지 않는 이유는 무엇입니까?

factcode 2022. 8. 18. 23:25
반응형

MSVS가 +0을 최적화하지 않는 이유는 무엇입니까?

질문은 매우 흥미로운 현상을 보여줍니다. 탈규격화된 플로트는 코드를 몇 배 이상 느리게 만듭니다.

행동은 인정된 답변에 잘 설명되어 있다.다만, 현재 153표 상승한 코멘트가 있습니다.다음 사항에 대해서는 만족스러운 답변을 찾을 수 없습니다.

이 경우 컴파일러는 +/- 0을 삭제하지 않는 이유는 무엇입니까?마이클 도건

사이드 노트:나는 0f가 정확히 표현되어야 한다고 생각하지만(더 나아가 이진수 표현은 모두 0이어야 함), c11 표준에서는 그러한 주장을 찾을 수 없다.이를 입증하는 인용문이나 이 주장을 반박하는 논거가 가장 환영할 것입니다.어쨌든 마이클의 질문이 여기서 가장 중요한 질문입니다.


§5.2.4.2.2

실장에서는, 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

반응형