自守数的计算探讨

myh9999 2004-10-29 02:42:40
何谓自守数?
  在郭先强先生编写的Automorphic Number程序中进行了如下的定义:
  【自守数】(在十进位制中,) 若一个 k 位正整数 N (可含前置 "0" ), 若满足如下性质: 任意两个或多个均以该字串 N 结尾的整数相乘, 其结果的最后 k 位数字一定还是 N, 那么, 则称 N 为 "k 位自守数".
  前几日偶然访问到下面的页面
  http://zhjyx.hfjy.net.cn/Resource/Book/Edu/SZJY/TS007047/0004_ts007047.htm
  在这个页面中介绍了下面的方程的两个无限解(0和1是两个显然的解)
x^2=x
  由此受到启发,编写的一段代码,经过一周左右的反复修改,实现了用计算机来快速求小于等于1,000,000,000的自守数。(事实上以现在的计算机速度和内存,计算10^8以下的数据比较现实一些)
  我的代码是以VC编写的一个控制台程序,使用内联汇编,未采用MMX或SSE等指令集,只使用了普能的X86指令。速度与郭先生的程序相比,在位数较小时,比如10万以下,略慢一点(小于1s),但在50万以上,速度略快,大约快2-3%左右。本人对MMX和SSE指令不熟悉,如果用其来优化核心代码,可能速度还能提高。
  算法的核心就是如何求5的2^n次方(但不需要求出全部数据,而只需要取低n位十进制数)。
  如有兴趣者,可以查看上面的页面,也可与我讨论.需要代码请发邮件给我:  
   myh9999@vip.sina.com
  
  待我整理好代码后,将贴出我的代码
  
  



...全文
654 44 打赏 收藏 转发到动态 举报
写回复
用AI写文章
44 条回复
切换为时间正序
请发表友善的回复…
发表回复
mathe 2004-11-09
  • 打赏
  • 举报
回复
20s now. So 27% speedup.
gxqcn 2004-11-08
  • 打赏
  • 举报
回复
我又改进了算法,在我的机器上计算 n=2^24 时速度提高了 30% 左右。

to myh9999 (虎子) & mathe():
我已将最新版发送给你们。

to mathe():
由于没有 ftp 权限,所以无法下载Intel C/C++编译器和VTune。
可否请你对新版再用 VTune 进行测试?谢谢!
mathe 2004-11-05
  • 打赏
  • 举报
回复
能不能提供一个没有图形界面的,像我的程序一样,只有命令行的,这样分析程序的性能比较简单。
比如我的程序,在n=10^7 (或2^24)时,估计有一半的时间花费在访问内存上。其中L2 Miss次数大概在100M
mathe 2004-11-05
  • 打赏
  • 举报
回复
呵呵,计算出10^8,花费2分46.516秒,但是不知道为什么,结果没有输出出来,估计可能输出列表框出问题,放不下了。计算过程中最多也就花700多M内存,不错:)
mathe 2004-11-05
  • 打赏
  • 举报
回复
呵呵,不过你的程序很好,内存消耗很小,在我的计算机上计算n=10^8肯定没有问题,我的程序就Outofmemory了:)
mathe 2004-11-05
  • 打赏
  • 举报
回复
呵呵,我知道可以那样计算,不过我偷懒,不愿意去修改。

在我的Windows 机器上做了试验,你的程序使用的内存明显比较少。
CPU 2.8G, L2 Cache 512M, Bus Clock 400M
在没有运行我们的程序时,内存使用450M
运行我的程序后,内存使用900M,时间15.436s (包含文件IO时间)
运行你的程序后,内存使用493M,时间17.141s

由于我的程序没有做位数优化,所以我有做了下n=2^24=16777216时候的比较
运行我的程序后,内存不变,时间是16.156s (同前面的唯一差别应该是在IO上)
运行你的程序后,内存使用534M,时间27.375s

xdspower 2004-11-05
  • 打赏
  • 举报
回复
我觉得自守数表示为表达式时需要定义一些算术符号,比如位数运算{x},表示十进制数x的位数,高位可以有不定个数的0,但整个数是确定位数的,比如{0001}=4,{001}=3,则定义自守数可以表示为一个
对于非负整数N,有{N}=k,(N^2 mod 10^k)=N
一位的自守数有0,1,5,6
gxqcn 2004-11-05
  • 打赏
  • 举报
回复
其实,可以反推每次的有效位数。比如:计算 n = 10^7,
可以记录如下值:10000000,5000000,2500000,1250000,625000,312500,156250,156250,78125,39063,19532,9766,4883,2442,...,直到达到一个可直接初始化的值。
而后反算即可。

to mathe():
我已将最新版发到你的信箱,请注意查收。请你在你的系统上运行测试,并希望得到相应的测试结果,如计算速度,输入、输出耗时,内存消耗等,谢谢!
mathe 2004-11-05
  • 打赏
  • 举报
回复
现在我用的算法还有一点比较浪费,就是计算10^7时,实际上计算的是
2^24=16777216位,所以很浪费,
比如如果只计算
2^23=8388608位,那么,内存就可以节省一半多的时间了。
其实如果计算时不是每次都增加一倍的位数,那么可以加快很多的。
mathe 2004-11-05
  • 打赏
  • 举报
回复
要看你如何进行乘法运算。在使用FFT进行乘法运算时,计算平方花费的时间是普通乘法的2/3,所以
用(x^2-1)^2 mod 10^(2k) 会比其他公式要快一些。
我上面的程序主要的缺点是内存消耗比较大,原因很简单,我使用了Intel的通用的FFT程序,程序没有专门为数据量很大的时候考虑过,所以在进行大数运算时,消耗内存过大。而这时,内存访问的速度成为主要制约因素了。其实这时,决定程序运行速度的主要因素在于内存访问的速度,而不是CPU的速度。不过我用的计算机是服务器 (Intel Xeon CPU),L2 Cache的大小是512K,所以在内存访问的速度上肯定也比你的机器占优势的。
从运行时间的比较,在n=5,6,7,基本上是我的计算机上的数据比你的快了一倍,所以算法复杂度看来
是一样的,很可能运行速度差不多(假设我的计算机综合性能是你的一倍是比较合理的)。但是我现在的程序对内存的要求比较高,这个是明显的缺点。如果在你的计算机上运行,对于10^7肯定会比较慢,因为你的计算机的内存只有256K,如果有512K,那就会好很多。
我记得用DCT(离散余弦变换)也应该可以做卷积运算的,如果改成用DCT运算应该可以节省一倍的内存的,但是对于如何用DCT做卷积我不是很确定,所以没有做试验。
你应该是用Windows吧,可以从:
https://shale.intel.com/EvalCenter/EvalForm.aspx?ProductID=254
下载Intel的MKL for Windows, 要求有个Email地址,Intel会将一个试用的版权文件发到你的信箱的,里面有如何下载和使用MKL的说明。
然后还要到http://www.intel.com/software/products/noncom/
下载MKL的库文件。
gxqcn 2004-11-05
  • 打赏
  • 举报
回复
受益非浅,谢谢!
mathe 2004-11-05
  • 打赏
  • 举报
回复
一般来说,用汇编不见得会有很好的效果,除非你对计算机体系结构非常了解,即使这样,很多东西还是人很难理解的。用好的编译器得到的效果可能会比用自己写汇编程序会好。当然,在写c程序时如何写代码也是比较重要的,如果你能够对编译器比较了解,会有很大的帮助。
上面的数据是用Intel的VTune来分析的,通上面发给你的网址上相关链接也可以找到VTune.还有Intel C/C++编译器也不错,对优化程序肯定有帮助。上面还有一些现成的算法也非常有用(比如我直接使用了FFT)。
上面cycles是指整个程序运行的时钟周期数目,其实这个从程序运行的时间也可以估算出来,比如机器主频2.8G,运行45.8G个cycles,那么就运行了45.8G/2.8G秒了。
instructions是只总共执行的机器指令数目(同汇编指令一一对应),而循环里面被反复执行的指令要重复计算的。由于现在的机器一般都有好多个处理单元,如果内存访问比例不高,优化的好的程序的IPC (instructions/cycles)会大于1的。 L1,L2 miss是指计算机访问内存数据时,这个数据没有在对应的Cache里面,所以计算机要首先将数据从内存读入Cache,或者从L2 Cache读入L1 Cache.而计算机直接访问内存是非常慢的,反问L1要比L2快很多。上面两个程序的Cache Miss Ratio很高(将近100%),也就是说,大部分需要访问的数据都不在Cache里面。DTLB是一个用来将线性地址(计算机中程序所以的内存地址)转化为物理地址(实际内存地址)的表格。同样这个表格也挺大的,不能全部放入Cache,所以也会有Miss,这时,访问内存就更慢了。

gxqcn 2004-11-05
  • 打赏
  • 举报
回复
to mathe():
可否解释一下上面一排各项指标的含义?以及介绍一下如何使它们各自向好的方向优化的技术与经验?另外,这些数据是如何测得的?我想为以后的开发引入更科学的评判数据,谢谢!
gxqcn 2004-11-05
  • 打赏
  • 举报
回复
上述报告我未完全看明白,但大致了解了一个梗概,谢谢!

需要说明的是,我的程序虽然用汇编优化过(包括输出我都做过特别优化),但却未用到MMX和SSE指令,与硬件的衔接不够,这是我的一个薄弱环节。

另外,高精度乘法会根据不同规模选用不同的算法,其临界点的设定以及算法中的某些常量只是满足在我的机器上接近最佳,比方说我未充分用到 L1/L2 Cache.
mathe 2004-11-05
  • 打赏
  • 举报
回复
上面是n=2^24的数据:cycles/2.8G就是运行时间。
一般来说,L2 Miss的代价在100-200个cycles,L1 Miss可能10个cycles以内,DTLB Miss的代价比L2还要大,应该在200以上。CPU主频在2.8G,可以看出调用Intel FFT的程序时间基本上花费在内存访问上,所以它的Instruction/Cycles非常低,才0.2左右。所以这个代码在计算上已经没法优化了,如果要优化应该在内存访问上做优化。
gxqcn的代码花费在内存访问上的时间大概在20%吧(估计的,肯定不准)。其中DTLB miss ratio特别高,是不是说明访问数据比FFT版本更加随机。现在计算所占的比例还是比较高的,可以试一试换一个好一点的编译器看看,我觉得可以有所提高的。
mathe 2004-11-05
  • 打赏
  • 举报
回复
cycles instructions UseMMX UseSIMD L1 Cache Miss L2 Cache Miss L1 Miss Ratio L2 Miss Ratio DTLB Miss DTLB Miss Ratio
Intel FFT 45.8G 9.55G Yes NO 568M 177M 95.08% 95.89% 41.8M 82.10%
gxqcn's code 76.2G 46.22G NO NO 421M 115M 91.39% 92.58% 112M 88.78%
gxqcn 2004-11-05
  • 打赏
  • 举报
回复
to mathe():
AutomorphicNumber_Console.exe 已发给你了,请分析其性能。
gxqcn 2004-11-04
  • 打赏
  • 举报
回复
to mathe():
我曾用过 (x^2-1)^2 mod 10^2k 去计算,它的优点是代码简单,但效率欠佳,因为第二次平方将浪费太多。

可否与我的程序进行一下横向对比?我想借此机会检验一下我的算法库,包括计算时间、输入输出、内存消耗等各个方面。

我的 E-mail 是 gxqcn@163.com. 我可以将最新的 AutomorphicNumber.exe 及算法库 HugeCalc 提供给你使用;或者,你可以把你的程序及那个“Intel的Math Kernel Library”传给我,以便在相同的操作环境下对比。(从你提供的数据分析,我的 HugeCalc 似乎更优一点,不过这需要同台对比才可下定论。)
mathe 2004-11-04
  • 打赏
  • 举报
回复
重新运行了一次n^7,时间14.77s,其中文件输出占1.1s.
mathe 2004-11-04
  • 打赏
  • 举报
回复
试着下载了一个Intel的Math Kernel Library, 用里面的FFT来计算平方运算,使用算法:
(x^2-1)^2 (mod 10^2k)

#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <mkl_fft.h>
#define MOD (10000)
double *r;
double *tmp;
#ifdef _WIN32
typedef __int64 longlong;
#else
typedef long long longlong;
#endif

int main()
{
int i,n;

int k,k1,k2,c2;
scanf("%d",&k);
if(k<=1)return -1;
k2=k,c2=0;
while(k2){
c2++;k2>>=1;
}
k2=1<<(c2-1); //k2<=k and k2 is power of 2.
if(k2<k)k2<<=1;
r=(double *)malloc(sizeof(double)*(k2+2));
if(r==NULL){
printf("Out of memory\n");
return -1;
}
tmp=(double *)malloc(sizeof(double)*(2*k2+4));
if(tmp==NULL){
printf("Out of memory\n");
free(r);
return -1;
}

n=1;
r[0]=625.0;
while(4*n<k2){
//Step 1. calcuate r*r;
for(i=n;i<2*n;i++)r[ i ]=0.0;
dzfft1dc(r,2*n,0,tmp);
dzfft1dc(r,2*n,1,tmp);//The forward FFT
r[0]*=r[0];
for(i=1;i<=n;i++){
double re=r[ i ];
double im=r[i+n+1];
double nr=re*re-im*im;
double ni=re*im*2.0;
r[ i ]=nr;
r[i+n+1]=ni;
}
zdfft1dc(r,2*n,0,tmp);
zdfft1dc(r,2*n,1,tmp);
for(i=0;i<2*n-1;i++){
longlong w=(longlong)(r[ i ]+0.5);
r[ i ]=(double)(w%MOD);
w/=MOD;
r[i+1]+=(double)w;
}
//Step 2. r*r-1.0
r[0]-=1.0;
//Step 3. (r*r-1.0)Mod 10^(2n)
for(i=2*n;i<4*n;i++)r[ i ]=0.0;
dzfft1dc(r,4*n,0,tmp);
dzfft1dc(r,4*n,1,tmp);//The forward FFT
r[0]*=r[0];
for(i=1;i<=2*n;i++){//normalize
double re=r[ i ];
double im=r[i+2*n+1];
double nr=re*re-im*im;
double ni=re*im*2.0;
r[ i ]=nr;
r[i+2*n+1]=ni;
}
zdfft1dc(r,4*n,0,tmp);
zdfft1dc(r,4*n,1,tmp);
for(i=0;i<2*n;i++){//normalize
longlong w=(longlong)(r[ i ]+0.5);
r[ i ]=(double)(w%MOD);
w/=MOD;
r[i+1]+=(double)w;
}//discard digits after 2*n
n*=2;
}

k1=k/4;
printf("Result for k=%d is\n",k);
if(k%4){//Output first several digits:
int limit=1;
longlong val=(longlong)(r[k1]+0.5);
for(i=0;i<k%4;i++)limit*=10;
val%=limit;
printf("%0*d",k%4,(int)val);
}
for(i=k1-1;i>=0;i--){
int val=(int)(r[ i ]+0.5);
printf("%04d",val);
if(i%10==0)printf("\n");
}
printf("\n");
free(r);
free(tmp);
}

在我的计算机上 (CPU 2.8G RedHat8.1, Memory 256M),对于
n=10^6
时间:1.032s ((包含输入输出时间)
但是在n=10^7时候很慢,需要将近1分钟,这是因为这个程序消耗内存比较厉害,
在n=10^7时,加上动态联接库,需要的内存超过300M,所以就要使用虚拟内存了。
上面的算法是nlog(n)的。
在另外一台主频3G,内存2G的机器上
计算n^6是0.765s,n^7是16s. (包含输入输出时间)
不过n^8就没法计算了,要out of memory.
加载更多回复(24)
网络安全从我做起   一、意图      生活在当今的信息时代,人们在享受信息技术带来极大方便的同时,也面临着一个 更为严重的信息安全问题。尽管这方面的教训数不胜数,但还是有很多人仍然熟视无睹 ,意识淡薄,缺乏必要的网络安全知识,因此,如何安全规范地进行信息活动,预防计 算机病毒,防止利用计算机进行犯罪,以确保信息安全,这是信息活动过程中必须引起 足够重视的问题。   中学信息技术新课程标准中提出青少年要树立安全的信息意识,学会病毒防范、了 解信息保护的基本方法;了解计算机犯罪的危害性,养成安全的信息活动习惯。   二、教学目的:   1、通过网络安全课让学生了解计算机病毒的概念、特点、传播的途径及其破坏性; 通过网络搜索获取相关信息;懂得病毒防范一般措施;   2、通过网络安全课让学生了解病毒的传播途径和危害性;从学生的切身体验或网上 搜索,通过探讨研究,总结归纳获得解决问题的方法;通过案例学习,了解计算机安全 问题所造成的重大危害性;   3、通过网络安全课教育学生在应用计算机和网络过程中应遵纪法律,自觉、自律 ,提高安全意识,养成良好的用网行为习惯,遵全国青少年文明上网公约,不做有害 社会和他人的事情。通过网络安全知识的学习,提高学生的信息素养。   三、教学重点:   1、计算机病毒的概念、特点、传播的途径及其破坏性;   2、懂得病毒防范一般措施;   3、了解病毒的传播途径、危害性和网络犯罪。   四、教学难点:   1、通过探讨研究,能够总结归纳获得解决问题的方法;   2、掌握病毒防范一般措施和杜绝网络犯罪;   五、说教学方法   1、教法(15分钟):通过以往发生的网络安全重大事故和近期热门网络安全话题跟 班级同学初步了解当前形式。采用问题驱动的方法以达到教学效果。在课堂上引申出许 多同学们感兴趣网络安全话题进行思考和讨论。因为根据计算机这门学科的特点,计算 机知识在一定时间内会过时,必须要教会学生自学计算机新知识的方法,让学生学会思 考和观察,体会到自己解决问题后的乐趣,激发其学习积极性。   2、学法(15分钟):学生通过亲身的经历和几个个病毒实例的传播和破坏过程演示 ,了解病毒的传播途径和危害性;从学生的切身体验或网上搜索,通过探讨研究,总结 归纳获得解决问题的方法。通过案例学习,了解计算机安全问题所造成的重大危害性。   六、说教学思路和过程(15分钟)   (一)利用网络进行信息交流有哪些方式及其功能特点   1、丰富的资源共享   2、更为广泛、便利的信息交流与合作   (二)现代信息技术带来极大便利的同时,面临着更为严重的信息安全问题   1、举例说明网络带来的负面影响以及新的隐患问题?(学生活动)   2、了解计算机、网络技术的种种安全隐患问题   (三)明确病毒的概念和特点   1、什么是计算机病毒?计算机病毒有哪些特点?上网搜索相关内容   2、小组归纳,总结 计算机病毒是可以给计算机和网络造成危害的程序; 传染性、 破坏性、潜伏性、可触发性、不可预见性、寄生性   七、遵全国青少年文明上网公约:   要善于网上学习不浏览不良信息   要诚实友好交流不侮辱欺诈他人   要增强自护意识不随意约会网友   要维护网络安全不破坏网络秩序   要有益身心健康不沉溺虚拟时空 ----------------------- 网络安全从我做起全文共3页,当前为第1页。 网络安全从我做起全文共3页,当前为第2页。 网络安全从我做起全文共3页,当前为第3页。
计算机网络技术专业调研报告 一、中等职业教育计算机专业现状分析 随着网络技术与计算机软硬件技术飞速发展,社会对计算机人才的需求在发生变化 。目前,中等职业学校计算机网络专业课程的设置和教学方法,与计算机的发展及社会 对计算机专业人才的需求不相适应,学生所掌握的专业知识和技能在当前的形势下显得 过于单薄和简陋。毕业生除了在一些计算机应用水平较低的行业或机关从事相关工作外 ,已经无法适应飞速发展的信息社会对计算机人才高技能、高素质的需要。为了更好地 满足佛山地区经济社会发展对中等职业人才需求,促进我校计算机专业的发展,增强毕 业学生的竞争力与就业率。我校计算机网络专业全体教师在主管校长、教务主任的组织 下,积极地投入到社会调研活动中,通过深入细致的调研,进一步了解企业对中等职业 学校网络专业毕业生的需求、岗位所必需的专业知识、要求掌握的操作技能程度和工作 规范,重点了解企业培训员工的过程和具体方法,明确网络专业的专业定位、专业设置 及人才培养目标,对网络专业的教学方法进行深入探讨,最终形成本专业的人才培养方 案。 国务院常务会议研究部署加强职业教育工作会议,讨论并原则通过了《国务院关于大 力发展职业教育的决定》。会议提出了今后一个时期职业教育改革发展的目标任务,并重 点指出:职业教育要坚持以服务社会主义现代化教育为宗旨,以就业为导向,继续深化 职业教育改革,加强职业院校学生实践能力和职业技能的培养。统计数据表明,职业教 育网络技术相关专业的毕业生,大部分(80%以上)从事计算机销售与技术支持、数据录入 、办公文秘等岗位的工作,在计算机应用与软件人才链中处于最低端位置。在局域网管 理与维护、多媒体制作、网站管理与维护、网络编程等岗位上工作的职业学校毕业生相 对较少,而实际上这些岗位非常需要中职毕业生,中职毕业生在这里具有很大的就业的 空间。因此,我们认为,随着计算机的普及,社会不仅需要掌握计算机基础知识,具有 操作和维护计算机系统的人才,更加需要掌握一定的计算机组成原理、计算机网络等知 识,具备计算机网络组建、多媒体网页制作、网站建设与维护等能力的网络中等专业人 才。 二、本地区企业、用人单位调研论证 为及时掌握行业发展趋势和用工市场的变化,学校长期以来十分重视专业建设中的 专业调研工作,此项工作为计算机专业的发展提供了科学的依据,对学校研究未来几年 本专业的就业环境及用工需求变化,使学校及时调整本专业的发展方向,进行相应的改 革提供有效的、科学的参考。 近几年,学校多次到深圳华为总部、广州神州数码网络设备分公司、广州唯康技术有 限公司、联想电脑公司、佛山诚讯电脑有限公司、佛山科悦网络有限公司、佛山东方电 子有限公司、中国陶瓷新闻网、佛山医网天下科技公司、佛山倚天计算机网络工程有限 公司、佛山尔太电子科技公司、佛山浪潮信息技术公司、佛山市禅城区网视通电子公司 、禅盟科技有限公司、禅城区创越电脑公司等企业对计算机人才知识技能需求、岗位职 业能力等多方面进行了调研,对我校今后计算机技术类专业建设具有极其重要的借鉴作 用。 通过对本地企业的调查表明,佛山地区企业电脑化的程度比较高,但应用程度还处 于比较低的层次,企业有使用信息技术提升效率的愿望,有的近期还比较迫切,但是缺 乏相应的人才,特别是具有网络专长的人才:如一些企业建立了网站进行形象、产品、 业务宣传,但缺乏有网站管理和网页制作经验专业知识的人才,网站维护与发布依靠专 门的网络科技公司,内容更新不方便,处理在线信息不及时,耽误了时间和效益。虽然 现在有许多学计算机网络的大学毕业生,但他们愿去中小企业的人不多,去的人当中有 的懂这方面知识,但理论较好却操作很不熟练,有的眼高手低,简单的不想做,难一点 的不会做,有的觉得大材小用,工作不安心,跳槽速度快,给企业带来人为损失。由于 网络专业是一个发展中行业,社会需求量很大,中职学校开设培养网络技术人才的出路 很好。我们在调查中还发现,佛山市许多企业的信息化水平还不高,企业信息化也正是 发展的好时机,计算机网络人才需求量会逐年不断增长。 在调查中,企业和用人单位等对学我校培养计算机网络技术方向人才培养提出了不 少宝贵建议,归纳如下: "分 类 "要 求 " "计算机网络技"网页编辑人员、网络测试、计算机及网络管理人员、熟悉计算" "术毕业生就业"机操作的办公室职员(文秘)、售后技术支持、网络施工与测" "范围 "量、多媒体技术、计算机组装与维修、流水线操作工、信息采" " "集等 " "对计算机网络"纪律,上班聊天者诫;钻研,细心,有平衡心态。勤快,动" "技术人才的职"手能力强。好学,不懒惰,有自主学习能力,诚实,品行好," "业素质要求 "良好的团队意识。 " "对计算机网络"计算机英语知识,操作系统知识,计算机硬件知识,网络知识"

33,010

社区成员

发帖
与我相关
我的任务
社区描述
数据结构与算法相关内容讨论专区
社区管理员
  • 数据结构与算法社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧