首页 / 知识
关于.net:在C#中计算素数的最快方法?
2023-04-13 09:47:00

Fastest way to calculate primes in C#?我实际上对我的问题有一个答案,但是它没有并行化,因此我对改进算法的方法很感兴趣。 无论如何,对于某些人来说,它可能仍然是有用的。
也许我可以同时使用多个 通过使用双向链接列表交叉引用位数组,可以节省一些时间,因此您可以更快地前进到下一个素数。 同样,在您第一次击中新质数p时消除以后的合成-剩余的p的第一个合成倍数将是p * p,因为之前的所有内容都已消除。实际上,您只需要将p乘以列表中剩余的所有剩余质数即可,只要乘积超出范围(大于直到)就停止。 还有一些好的概率算法,例如Miller-Rabin测试。维基百科页面是一个很好的介绍。 除了并行化,您不想每次迭代都计算sqrt(Until)。您还可以假设2、3和5的倍数,并且仅计算{1,5}中的N%6或{1,7,11,13,17,19,23,29}中的N%30。 您应该能够非常轻松地并行化分解因式算法,因为第N个阶段仅取决于第sqrt(n)个结果,因此一段时间后不会出现任何冲突。但这不是一个好的算法,因为它需要大量划分。 如果您有保证可以在读取之前完成的写入器工作包,则还应该能够并行化筛子算法。通常,编写者不应与阅读器发生冲突-至少一旦完成一些输入,写作者就应该在阅读器之上至少N处工作,因此您仅需要偶尔进行同步读取(当N超过最后一次同步读取时值)。您不需要在任何数量的写程序线程上同步bool数组,因为不会发生写冲突(最坏的情况是,多个线程将在同一位置写入true)。 主要问题是确保等待写入的所有工作人员都已完成。在C ++中,您将使用"比较并设置"切换到随时等待的工作程序。我不是C#使用者,所以不知道该用哪种语言,但是Win32 InterlockedCompareExchange函数应该可用。 您也可以尝试使用基于actor的方法,因为这样可以安排使用最低值的actor,这可能更容易确保您正在读取筛网的有效部分,而不必在每次递增时都锁定总线。 N. 无论哪种方式,您都必须在阅读之前确保所有工作人员都高于条目N,而这样做的代价是要在并行和串行之间进行权衡。
如果您使用的是大型系统,则可以使用分析器来发现素数生成器是需要优化的部分。 分析其中包含十几条指令的循环通常是不值得的-与循环主体相比,探查器的开销很可观,而改善循环的唯一方法是减小循环的唯一方法是更改??算法以减少迭代次数。因此,IME一旦消除了任何昂贵的功能,并有了几行简单代码的已知目标,那么与尝试按指令级别改进代码相比,最好改变算法并定时进行端到端运行分析。
有一篇关于Eratosthenes筛子的好文章:Eratosthenes的真正筛子 它处于功能设置中,但是大多数优化也确实适用于C#中的过程实现。 两个最重要的优化是从P ^ 2而不是2 * P开始舍去,并使用转轮表示下一个质数。 对于并发性,您可以并行处理直到P ^ 2的所有数字,而不进行任何不必要的工作。 您是否正在寻找新的素数?这听起来可能很愚蠢,但是您可能能够加载已知素数的某种数据结构。我确定那里有人。找到计算新数字的现有数字可能会容易得多。 您还可以查看Microsoft的Parallel FX Library,使现有代码成为多线程以利用多核系统。通过最少的代码更改,您可以使for循环成为多线程的。 您还应该考虑算法的可能更改。 考虑到将它们简单地添加到列表中可能会更便宜。 也许为您的列表预分配空间将使构建/填充便宜。 @DrPizza Profiling确实只能真正帮助改进实现,它并不能揭示并行执行的机会,也不能建议更好的算法(除非您有其他经验,在这种情况下,我很想看看您的探查器)。 我家里只有单核计算机,但运行的Java等效于您的BitArray筛子,并且运行了筛子反转的单线程版本-将标记质数保存在数组中,并使用滚轮减少了搜索空间,乘以五分之一,然后使用每个标记质数以轮的增量标记位阵列。它还将存储减少为O(sqrt(N))而不是O(N),这在最大的N,分页和带宽方面均有所帮助。 对于N的中等值(1e8至1e12),可以很快找到sqrt(N)的质数,之后,您应该能够很容易地并行化CPU上的后续搜索。在我的单核机器上,滚轮方法可以在28s内找到最高达1e9的质子,而筛子(将sqrt移出回路后)需要86s-改进是由于滚轮;反转意味着您可以处理大于2 ^ 32的N,但会使其变慢。代码可以在这里找到。经过sqrt(N)后,您也可以并行处理朴素筛子的结果输出,因为在此之后,位数组不会被修改;但是一旦处理了足够大的N,那么数组大小对于int来说就太大了。 |
最新内容
相关内容
python中获取路径的三种方法
python中获取路径的三种方法,工作,代码,情况,培训,下来,路径,文件,也就是,桌面,目录,python中获取路径总结下来分为三种情况:1、获取工作目录怎样用python计算矩阵乘法?
怎样用python计算矩阵乘法?,位置,矩阵,培训,一致,乘法,数组,函数,示例,作用,标量,python中计算矩阵乘法的方法:1、使用np.multiply()函数计算Python中怎么计算圆周长?
Python中怎么计算圆周长?,公式,培训,圆周,半径,浮点,以上,结果,更多,内容,python中怎么计算圆周长呢?1、首先输入圆的半径2、其次将输入的半python列表有哪些常用方法?
python列表有哪些常用方法?,位置,方法,培训,列表,语法,元素,示例,对象,以上,参数,列表是最常用的Python数据类型,它可以作为一个方括号内的逗python如何计算程序运算时间
python如何计算程序运算时间,时间,系统,单位,培训,程序,方法,浮点,以来,类型,纪元,python计算程序运算时间的方法:方法1:importdatetimestarttiPython如何创建对象,有哪些方法
Python如何创建对象,有哪些方法,培训,对象,方法,内容,函数,属性,所在,以上,以下,功能,以下介绍Python创建对象的9种方法。classPoint:def__iniPython静态函数和普通方法的区别
Python静态函数和普通方法的区别,培训,方法,静态,区别,实例,函数,属性,结果,例子,下面,下面通过一个例子,讲解Python静态函数、普通方法、类方python中什么是类方法
python中什么是类方法,培训,方法,实例,静态,定义,参数,函数,内部,变量,属性,python中的类方法,指的是在类中定义的函数,函数在类的内部称为方法python算法有用吗
python算法有用吗,玩具,培训,算法,程序,存在,路径,也就是说,模型,场景,以上,有很多人说,学Python编程算法有用吗?学算法对于写程序来说非常重python看类里有哪些方法
python看类里有哪些方法,信息,员工,培训,名称,方法,函数,冒号,字符串,语句,结尾,python使用class语句来创建一个新类,class之后为类的名称并以python怎么调用方法
python怎么调用方法,系统,培训,方法,参数,法名,定义,列表,实例,以上,函数,python调用的方法类的方法的定义1、定义一个类deffun_name(self,..python对象与方法的区别是什么
python对象与方法的区别是什么,地址,数据,培训,对象,函数,类型,字符串,方法,表示,身份,python使用对象模型来存储数据,也就是说构造任何类型的