문제

내가를 수행하는 데 필요 많은 작업을 찾는의 나머지 부문 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 을 관찰하는 더 뜻깊은 시간 다름)

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top