Fortran (과학 컴퓨팅 용으로 설계됨)에는 전원 연산자가 내장되어 있으며, 내가 아는 한 Fortran 컴파일러는 일반적으로 설명하는 것과 비슷한 방식으로 정수 전력을 올릴 수 있도록 최적화합니다. 불행히도 C / C ++에는 파워 연산자가없고 라이브러리 함수 만 있습니다 pow()
. 이것은 스마트 컴파일러가 pow
특수한 경우를 위해 특별하게 처리 하고 더 빠른 방식으로 계산 하는 것을 방해하지는 않지만 덜 일반적으로 사용되는 것 같습니다 ...
몇 년 전에 나는 정수 전력을 최적의 방법으로 계산하는 것이 더 편리하도록 노력하고 있었고 다음을 생각해 냈습니다. 그것은 C가 아니라 C ++이며 여전히 최적화 / 인라인 방법에 대해 다소 똑똑한 컴파일러에 달려 있습니다. 어쨌든, 실제로 유용하게 사용될 수 있기를 바랍니다.
template<unsigned N> struct power_impl;
template<unsigned N> struct power_impl {
template<typename T>
static T calc(const T &x) {
if (N%2 == 0)
return power_impl<N/2>::calc(x*x);
else if (N%3 == 0)
return power_impl<N/3>::calc(x*x*x);
return power_impl<N-1>::calc(x)*x;
}
};
template<> struct power_impl<0> {
template<typename T>
static T calc(const T &) { return 1; }
};
template<unsigned N, typename T>
inline T power(const T &x) {
return power_impl<N>::calc(x);
}
궁금한 점에 대한 설명 : 이것은 전력을 계산하는 최적의 방법을 찾지 못하지만 최적의 솔루션을 찾는 것은 NP- 완전한 문제 이므로 (어떻게 사용하는 것과 달리) 작은 전력에 대해서만 가치가 pow
있기 때문에 소란 할 이유가 없습니다. 세부 사항으로.
그런 다음로 사용하십시오 power<6>(a)
.
이렇게하면 힘을 쉽게 입력 할 수 있고 (파 a
렌스로 6 초 를 철자 할 필요가 없음 ), 보상 합산-ffast-math
과 같은 정밀한 의존성이있는 경우 (작업 순서가 필수적인 예) 없이 이러한 종류의 최적화를 수행 할 수 있습니다. .
아마도 이것이 C ++임을 잊어 버릴 수 있으며 C 프로그램에서 사용하십시오 (C ++ 컴파일러로 컴파일하는 경우).
이것이 유용 할 수 있기를 바랍니다.
편집하다:
이것이 내 컴파일러에서 얻는 것입니다.
를 들어 a*a*a*a*a*a
,
movapd %xmm1, %xmm0
mulsd %xmm1, %xmm0
mulsd %xmm1, %xmm0
mulsd %xmm1, %xmm0
mulsd %xmm1, %xmm0
mulsd %xmm1, %xmm0
를 들어 (a*a*a)*(a*a*a)
,
movapd %xmm1, %xmm0
mulsd %xmm1, %xmm0
mulsd %xmm1, %xmm0
mulsd %xmm0, %xmm0
를 들어 power<6>(a)
,
mulsd %xmm0, %xmm0
movapd %xmm0, %xmm1
mulsd %xmm0, %xmm1
mulsd %xmm0, %xmm1