내 코드는 다음 않습니다 속도가 느려집니다 :바쁜 루프는 대기 시간이 중요한 계산
- 일부 장기 실행 강렬한 계산을 수행합니다 (아래라고 쓸모)
- 작은 대기 시간이 중요한 작업을 수행
대기 시간이 중요한 작업을 실행하는 데 걸리는 시간이 오래 걸리는 계산을 사용하는 경우보다 빠르다는 것을 알게되었습니다. 여기
이 효과를 재현하는 일부 독립 실행 형 C++ 코드 : 1 억USELESS
세트
-O3
로 컴파일 할 때
#include <stdio.h>
#include <stdint.h>
#define LEN 128
#define USELESS 1000000000
//#define USELESS 0
// Read timestamp counter
static inline long long get_cycles()
{
unsigned low, high;
unsigned long long val;
asm volatile ("rdtsc" : "=a" (low), "=d" (high));
val = high;
val = (val << 32) | low;
return val;
}
// Compute a simple hash
static inline uint32_t hash(uint32_t *arr, int n)
{
uint32_t ret = 0;
for(int i = 0; i < n; i++) {
ret = (ret + (324723947 + arr[i]))^93485734985;
}
return ret;
}
int main()
{
uint32_t sum = 0; // For adding dependencies
uint32_t arr[LEN]; // We'll compute the hash of this array
for(int iter = 0; iter < 3; iter++) {
// Create a new array to hash for this iteration
for(int i = 0; i < LEN; i++) {
arr[i] = (iter + i);
}
// Do intense computation
for(int useless = 0; useless < USELESS; useless++) {
sum += (sum + useless) * (sum + useless);
}
// Do the latency-critical task
long long start_cycles = get_cycles() + (sum & 1);
sum += hash(arr, LEN);
long long end_cycles = get_cycles() + (sum & 1);
printf("Iteration %d cycles: %lld\n", iter, end_cycles - start_cycles);
}
}
을 세 번 반복은 각각 588, 4184, 536 사이클을했다. USELESS
을 0으로 설정하면 컴파일은 각각 394, 358 및 362 사이클이 소요되었습니다.
왜 이것이 (특히 4184주기) 일어날 수 있습니까? 강렬한 계산으로 인해 캐시 미스 또는 분기 오 예측이 의심됩니다. 그러나 강렬한 계산이 없으면 대기 시간이 긴 태스크의 반복 횟수가 매우 빠르기 때문에 차가운 캐시/분기 예측자가 원인이라고 생각하지 않습니다.
'get_cycles()'가 내부 루프보다 먼저 재정렬됩니다. 어셈블러를 살펴보십시오. – Jarod42
4184 아웃 리어 (outlier)는 OS 나 다른 프로세스와 같은 컨트롤에서 벗어난 것으로 인해 발생할 수 있습니다. 또한 최신 멀티 코어, 다중 주파수 컴퓨터에서 rdtsc의 정확성은 불확실합니다. – user4581301
@ Jarod42 - 확인했습니다. 재정렬되지 않았습니다. –