【发布时间】:2018-10-31 10:51:07
【问题描述】:
我有大量的模数计算要执行。基本计算如下:
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 可以知道 answer[i - 1] 帮助您更快地获得 answer[i])?任何其他改进或建议将不胜感激。
【问题讨论】:
-
也许你可以从this源应用快速模数。
-
除非
prime序列和/或start有一些特殊的属性,我怀疑没有更快的方法。通常给定足够大的start,您可以将answer[i]设为某些i的任何值,而使所有其他answers 相同(请参阅Chinese remainder theorem)。 -
加速此例程的唯一可行方法是并行运行其中的一部分。
-
这确实是边缘情况,但用浮点算术模拟模更快(已经在标量代码中)并且还可以矢量化
-
我的实现已经使用了多线程并行(未显示)。至于数据并行性或矢量化,我遇到的问题是“开始”可以超过 2^53 -1(最大 int 而不会丢失转换精度)。除法仅存在于非整数运算中的 x86 向量化内在函数。除了从整数到双精度的转换(反之亦然)会减慢它的速度,向量化也仅限于一次只有 2 个双精度。是的,向量双除法比单个整数除法更快。所有伟大的想法,但对我有一些限制。
标签: algorithm performance math optimization simd