가속 성능의 반복 수행하 unsigned long long 모듈 작업
-
23-12-2019 - |
문제
내가를 수행하는 데 필요 많은 작업을 찾는의 나머지 부문 unsigned long long
숫자 16 비트률:
unsigned long long largeNumber;
long residues[100];
unsigned long modules[100];
intiModules(modules); //set different 16-bit values
for(int i = 0; i < 100; i++){
residues[i] = largeNumber % modules[i];
}
는 방법을 가속할 수 있는 이 루프?
반복 횟수가 크지 않은(32-128)지만,이 루프 수행에 매우 자주 그래서 그 속도는 매우 중요합니다.
해결책
사단에 의해 일정한(그리고만 있 65536 그들의)에 의해 수행할 수 있습의 곱셈 상호 뒤/앞에는 일부 세밀한 조정이 가능합니다.이후 이 방법은 정확한 제한된 범위나 사용할 수 있는 몇 가지 기술을 줄이는 64 비트 연산자를 훨씬 작은 값(아직도에 적합한 원래 값):
// pseudo code -- not c
a = 0x1234567890abcdefULL;
a = 0x1234 << 48 + 0x5678 << 32 + 0x90ab << 16 + 0xcdef;
a % N === ((0x1234 * (2^48 % N) + // === means 'is congruent'
(0x5678 * (2^32 % N)) + // ^ means exponentation
(0x90ab * (2^16 % N)) +
(0xcdef * 1)) % N;
중간 값을 계산할 수 있습과(작은)곱셈만 최종 나머지 부분(%N)는 잠재적 계산할과 상호 수 있습니다.
다른 팁
는 경우 속도는 매우 중요에 따라 이 응답에 대한 분기 예측 고 이, 루프 풀 수 있습의 도움을 피하고,테스트에 의해 유도 된 대 명령의 수를 줄이고,테스트 및 개선하"분기 예측".
의 증가(또는 아무도 일부러 하는 최적화에 대한 당)기간에 따라 다름 아키텍처/컴파일러입니다.
내 컴퓨터에서 변경,루프 유지하면서 번호의 작업에서
for(int i = 0; i < 500000000; i++){
residues[i % 100] = largeNumber % modules[i % 100];
}
하기
for(int i = 0; i < 500000000; i+=5){
residues[(i+0) % 100] = largeNumber % modules[(i+0) % 100];
residues[(i+1) % 100] = largeNumber % modules[(i+1) % 100];
residues[(i+2) % 100] = largeNumber % modules[(i+2) % 100];
residues[(i+3) % 100] = largeNumber % modules[(i+3) % 100];
residues[(i+4) % 100] = largeNumber % modules[(i+4) % 100];
}
가 gcc -O2
이득~15%입니다.(500000000 신의 100 을 관찰하는 더 뜻깊은 시간 다름)
제휴하지 않습니다 StackOverflow