我有大量的模数计算要执行。基本计算如下:
const uint64_t start; // Some "large" number that does NOT change
uint32_t prime[bigNumber]; // Precalculated sequential prime numbers (generated on the fly from a bit compaction storage method for space reasons).
uint64_t answer[bigNumber]; // The "modulo" answers
for (uint64_t i = 0; i < bigNumber; i++) {
uint32_t factor = prime[i];
answer[i] = (factor - 1) - ((start - 1) % factor);
}
注意:start通常比prime [i]大得多。
有没有更快的方法来计算“答案”而不执行每次迭代的模/除(AKA可以知道答案[i - 1]帮助你更快地得到答案[i])?任何其他改进或建议将不胜感激。
答案 0 :(得分:0)
我想回答一些上述评论的部分答案。它可以帮助你一次做多个mod。
if (start < (1ULL << DBL_MANT_DIG)) {
__m256d div1 = _mm256_broadcastsd_pd(_mm_cvtsi64_sd(_mm_setzero_pd(), start - 1));
__m128i one = _mm_set1_epi32(-1);
__m128i fact = *(__m128i *)(&prime[i]);
__m256d div2 = _mm256_cvtepi32_pd(fact);
__m128i rem = _mm256_cvtpd_epi32(_mm256_fnmadd_pd(
_mm256_floor_pd(_mm256_div_pd(div1, div2)), div2, div1));
*(__m256i *)(&answer[i]) = _mm256_cvtepu32_epi64(_mm_sub_epi32(fact,
_mm_sub_epi32(rem, one)));
}
如果您对此部分答案有所改进,请发表评论。