Program Tip

곱셈이 부동 나누기보다 빠릅니까?

programtip 2020. 11. 5. 18:51
반응형

곱셈이 부동 나누기보다 빠릅니까?


C / C ++에서 다음 코드를 설정할 수 있습니다.

double a, b, c;
...
c = (a + b) / 2;

이것은 다음과 똑같은 일을합니다 :

c = (a + b) * 0.5;

어느 것이 더 나은지 궁금합니다. 한 작업이 다른 작업보다 근본적으로 더 빠릅니까?


곱셈은 ​​나눗셈보다 빠릅니다. 대학에서 나는 나눗셈이 곱셈의 6 배라는 것을 배웠다. 실제 타이밍은 아키텍처에 따라 다르지만 일반적으로 곱셈은 나눗셈만큼 느리거나 느리지 않습니다. 반올림 오류가 허용되는 경우 항상 곱셈을 사용하도록 코드를 최적화하십시오.

따라서 예에서 이것은 일반적으로 더 느립니다 ...

for (int i=0; i<arraySize; i++) {
    a[i] = b[i] / x;
}

... 이것보다 ...

y=1/x;
for (int i=0; i<arraySize; i++) {
    a[i] = b[i] * y;
}

물론 반올림 오류의 경우 두 번째 방법을 사용하면 정밀도가 약간 x=1/x;떨어질 수 있지만 반복적으로 계산하지 않는 한 많은 문제가 발생하지 않을 것입니다.

편집하다:

참고 용입니다. Google에서 검색하여 운영 타이밍에 대한 타사 비교를 파헤 쳤습니다.

http://gmplib.org/~tege/x86-timing.pdf

MUL과 DIV의 숫자를보십시오. 이는 프로세서에 따라 5 ~ 10 배 차이가 있음을 나타냅니다.


부동 소수점 곱셈은 일반적으로 부동 소수점 나누기보다주기가 적습니다. 그러나 리터럴 피연산자를 사용하면 옵티마이 저는 이러한 종류의 마이크로 최적화를 잘 알고 있습니다.


이 경우 컴파일러가 분할을 곱셈으로 변환 할 가능성이 높습니다. "생각"하면 더 빠릅니다. 부동 소수점에서 2로 나누는 것도 다른 부동 나누기보다 빠를 수 있습니다. 컴파일러가 변환하지 않으면 곱하기를 사용하는 것이 더 빠를 수 있지만 확실하지는 않습니다. 프로세서 자체에 따라 다릅니다.

나누기 대신 곱하기를 수동으로 사용하여 얻을 수있는 이득은 컴파일러가 그렇게하는 것이 "안전"하다고 판단 할 수없는 경우 매우 클 수 있습니다 (예 : 0.1은 부동 소수점 숫자에 정확히 0.1로 저장할 수 없으며 0.10000000149011612가됩니다. ). 클래스를 대표하는 AMD 프로세서에 대한 그림은 아래를 참조하십시오.

컴파일러가이 작업을 잘 수행하는지 여부를 알기 위해 약간의 코드를 작성하여 실험 해 보는 것이 좋습니다. 컴파일러가 상수 값을 계산하지 않고 루프의 모든 계산을 버리도록 작성하십시오.

편집하다:

가족 15H 프로세서를위한 AMD의 최적화 가이드에 대한 수치를 제공 fdiv하고 fmul- 42, 6은 각각. SSE 버전은 DIVPS, DIVPD DIVSS 및 DIVSD (나누기)의 경우 24 (단일) 또는 27 (더블) 사이클, 모든 형태의 곱셈에 대해 6 사이클로 조금 더 가깝습니다.

메모리에서 인텔의 수치는 그리 멀지 않습니다.

참고 URL : https://stackoverflow.com/questions/17883240/is-multiplication-faster-than-float-division

반응형