본질적으로 오버 플로우에 따라
k_0 = h_1 mod s
k_1 = h_1 + h_2 mod s = k_0 + h_2 mod s
k_2 = h_1 + h_2 + h_2 mod s = k_1 + h_2 mod s
..
k_n = k_(n-1) + h_2 mod s
을하고있는 (크기가 2**64
의 절반보다 작 으면 원본과 다르지 않아야합니다.)이 경우 더 빠르지 만 (병렬 처리는 쉽지 않음)
uint64_t h_one = hash[0];
uint64_t h_two = hash[1];
k_hash[0] = h_one % size;
for (int i=1; i<k; ++i)
{
(uint64_t *) k_hash[i] = (k_hash[i-1] + h_two) % size;
}
참고 : 사용하는 최적화 플래그에 따라 컴파일러가 이미이 형식을 사용했을 가능성이 있습니다.
물론 이것은 하나의 곱셈 만 제거했습니다. 당신이 제거 또는 모듈을 줄이려면,이 같은, 당신은 당신이 명시 적으로 %size
를 호출해야하는 단계를 미리 결정할 수 h_1%size
뭔가를 h_two%size
에 따라 추측과 :
uint64_t h_one = hash[0]%size;
uint64_t h_two = hash[1]%size;
k_hash[0] = h_one;
step = (size-(h_one))/(h_two)-1;
for (int i=1; i<k; ++i)
{
(uint64_t *) k_hash[i] = (k_hash[i-1] + h_two);
if(i==step)
{
k_hash[i] %= size;
}
}
주 나는 확실하지 않다 공식 (테스트하지 않았다), 그것은 더 일반적인 생각이다. 이것은 분기 예측이 얼마나 좋은지 (그리고 예측 실패가 얼마나 큰지)에 달려 있습니다. 또한 단계가 큰 경우에만 도움이 될 수 있습니다.
편집 : 이상 간단한 (그리고 아마도 같은 성능)은 신비로운에 고마워요 :
uint64_t h_one = hash[0]%size;
uint64_t h_two = hash[1]%size;
k_hash[0] = h_one;
for (int i=1; i<k; ++i)
{
(uint64_t *) k_hash[i] = (k_hash[i-1] + h_two);
if(k_hash[i] > size)
{
k_hash[i] -= size;
}
}
당신이'size'에 대해 아무것도 알고 있습니까? – Mysticial
당신이 요구 한대로 몇 가지 사항을 명확히하기 위해 질문을 편집했습니다. –
똑같은 번호에 대해 반복되는 나누기/모듈러스를 만드는 방법이 있습니다. 그러나 그것은 사소한 것이 아닙니다. – Mysticial