개정 문제는 (당신이 그것을 쓸 수 있다면 어떤 당신은 할 수 없습니다) 대신
cpdef float interpolate_lit(float start, float end, float alpha):
return end * alpha + start * (1.0f - alpha)
의
cpdef float interpolate_cast(float start, float end, float alpha):
return end * alpha + start * (<float>1.0 - alpha)
을 쓰기에 대한 런타임 성능 저하가 있는지 여부입니다.
일반적으로에서이 유형의 질문에 대한 대답은 "물론 아닙니다. 컴파일러는 정확하게 동일한 기계 코드를 생성합니다 (최적화 도구를 켜 놓았는지 확인하십시오)"; 부동 소수점을 최적화하는 방법에 대한 명확하지 않은 제한이 있기 때문에 부동 소수점에 대해서는 항상 그렇지 않습니다. 이 경우에는 1.0
이 정확히 float
에 표시 될 수 있기 때문에 꽤 안전한 내기이지만, 알아내는 방법을 알려 드리겠습니다.
CPython의 통합 접착제 엄청난 양을 박리 한 후,이 사이 썬 상기 제 함수 생성하는 코드이다 : I 수동 1.0f
변경 (float)1.0
이 함수의 두 번째 복사본을 생성
float interpolate_cast(float start, float end, float alpha) {
float r;
r = ((end * alpha) + (start * (((float)1.0) - alpha)));
goto L0;
L0:;
return r;
}
은 그리고 -O2 -march=native
및 이 아닌을 사용하여 x86-64의 GCC 6.3을 사용하여 -ffast-math
을 사용하여 컴파일했습니다.
interpolate_cast:
vmovss .LC0(%rip), %xmm3
vsubss %xmm2, %xmm3, %xmm3
vmulss %xmm0, %xmm3, %xmm0
vfmadd231ss %xmm2, %xmm1, %xmm0
ret
interpolate_lit:
vmovss .LC0(%rip), %xmm3
vsubss %xmm2, %xmm3, %xmm3
vmulss %xmm0, %xmm3, %xmm0
vfmadd231ss %xmm2, %xmm1, %xmm0
ret
.LC0:
.long 1065353216
그래서 당신은 정확히 같은 어느 쪽이든 나오는 것을 볼 수있다 :이 (다시, 관련없는 잡담의 무리가 제거 된) 내가 가진 어셈블리 코드입니다. (신비한 숫자 1065353216
은 0x3f800000
입니다. 1.0f
입니다.)이 컴파일러가 똑같은 일을하는지 MSVC에서이 실험을 반복 할 수 있습니다. 나는 그것을 기대할 것이다.
이 기능이 성능에 중요한 영향을 미치는 경우 벡터화를 고려해야합니다. 예를 들어,이 C 연산 커널 작성할 수
#include <stddef.h>
void interpolate_many(float *restrict dest,
float const *restrict start,
float const *restrict end,
float const *restrict alpha,
size_t n)
{
for (size_t i = 0; i < n; i++)
dest[i] = end[i] * alpha[i] + start[i] * (1.0f - alpha[i]);
}
을 적절 형식의 NumPy와 배열을 취 그 주위에 사이 썬 래퍼를 넣어. GCC는 이것을 자동 제어 할 수 있습니다. MSVC도 가능해야하며 Intel의 컴파일러는 확실히 할 수 있습니다. Cyber에서 커널을 작성하려고하지는 않을 것입니다. 아마도 autobctorizer를 활성화하기에 충분하게 주석을 달 수 없기 때문입니다. const
및 restrict
은 필수적입니다.
Cython에서'1.0f'를 쓸 수없는 것 같습니다. '( 1-alpha)'시도해보십시오.그러면 생성 된 C 코드에서'(((float) 1) - alpha)'가 생성됩니다. 나는 MSVC가 그것에 관하여 경고 할 것인지 아닌지를 모른다. '1' 또는'1.0'을 사용 하느냐가 중요 할 수 있습니다. –
zwol
런타임 성능에 대해서는 중요하지 않지만, 100 % 확신하려면 생성 된 어셈블리 코드를 검사해야합니다. – zwol