Dev-C++ 5.9.2 Profile Analysis 使用

版权声明:本文为博主原创文章,遵循 CC 4.0 by-sa 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/ndfeixia/article/details/51055914

1. Execute -> Delete... -> compile and run -> Execute -> Profile Analysis

2. 选择Call graph标签页(Flat output 有时为空,有时有内容?)。

3. 观察到,每个entry包含若干lines。在每个entry内,找到Index项不为空的那一行。在此entry内,此行之上,为所有调用此function的其它函数;此行之下,为所有此function调用的其他函数。

3.1. 此处的“调用”关系,仅包含一级。如,main CALL a CALL b, 则b不在main的entry内显示。除非此后有main直接CALL b的语句。

3.2. 这个特定的行对应的函数被称作 current function,姑且称作当前函数。这一特定行可称作当前行。

3.3. 即,每一项 与 当前函数 一一对应。

4. 针对当前函数,在当前行内可以得到的某些有用信息:

4.1. 用%time项,或self + children,可以得到从当前函数开始的整条函数调用链的耗时(或其占比)。

4.2. 比较self和children,若self明显大,则time consumption的主要contributor是当前函数的自己的函数体。

4.3. 用called项,可以得到此函数在整个running time被call的次数。其格式为:nonrecursion (+ recursion)。

5. 针对当前函数(设为X)的父函数(设为F,必然位于entry内的当前行的上方):

5.1. F行中的self表示,在F的函数调用链中,X的函数体耗时。

5.2. F行中的children表示,在F的函数调用链中,X的函数调用链耗时,其中不含X的函数体耗时。

5.3. F行中的Called表示,F调用X的次数 / 任意函数调用X的次数。即此项可看出当前函数是否主要由某父函数调用。越接近1,则X越专一归属于F。

6. 针对当前函数(设为X)的子函数(设为C,必然位于entry内的当前行下方):

6.1. self:X的调用链中,C的函数体耗时。

6.2. children:X的调用链中,C的调用链,除C函数体,耗时。

6.3. X调用C的次数 / 任意函数调用C的次数。即越接近1,C越专一归属于X。

7. spontaneous标签?

8. 有时Function name项有缩进?


Illustration:

今天首次接触、使用Call Graph,来查信安作业的大数运算代码,主要是DH算法里的幂模运算,速度很慢,希望提高效率。发现主要是乘法调用链(只是调用了进位函数spread)比较耗时。其中,函数体本身又占了59.3%的将近2/3的时间,大约是running time的40%。

于是把重心放在改进mul函数上。

BN mul(BN bn1, BN bn2){
	BN result;

	for(int i = 0; i<SoULL; i++){
		for(int j = 0; j<SoULL; j++){

			result.V[i+j] += (bn1.V[i] * bn2.V[j]) % (MNB+1);
			result.spread(i+j);
			result.V[i+j+1] += (bn1.V[i] * bn2.V[j]) / (MNB+1);
			result.spread(i+j+1);

		}
	}
	return result;
}

我认为bn1.V[i] * bn2.V[j]要算2遍,浪费,应该先存起来才对,下次可以直接用。于是改了代码:

BN mul(BN bn1, BN bn2){
	BN result;
	ull tmp;
	ull MNBPLUS;
	for(int i = 0; i<SoULL; i++){
		for(int j = 0; j<SoULL; j++){
			tmp = bn1.V[i] * bn2.V[j];
			MNBPLUS = MNB + 1;
			result.V[i+j] += tmp % MNBPLUS;
			result.spread(i+j);
			result.V[i+j+1] += tmp / MNBPLUS;
			result.spread(i+j+1);


		}
	}
	return result;
}


再次运行,居然时间变多了。spread的时间倒是稳定,函数体竟然比原先慢了2倍(变成6秒多)。只好改回原来的。

看来,把大数存起来再取,还不如多次运算?

我发觉,spread的调用次数可以减少。只要在spread前加一个if判断。这也是改进代码的另外一个思路——除了改变数据的获得方式,还可以改变程序的运行策略。

BN mul(BN bn1, BN bn2){
	BN result;

	for(int i = 0; i<SoULL; i++){
		for(int j = 0; j<SoULL; j++){

			result.V[i+j] += (bn1.V[i] * bn2.V[j]) % (MNB+1);
			if(result.V[i+j] > MNB)result.spread(i+j);
			result.V[i+j+1] += (bn1.V[i] * bn2.V[j]) / (MNB+1);
			if(result.V[i+j+1] > MNB)result.spread(i+j+1);

		}
	}
	return result;
}

结果大大加快了:


比较诧异的其他现象:%time更多了(留意到,此前的main就是60%,并参见上一张图,可以得到,mul占main的时间其实不变,但是running time除了main的时间大幅缩小到了1.6%);self居然也会降低?

展开阅读全文

DEV-C 源码转VC 问题

07-16

DEV-C 编的 能否改动一下使能在VC下运行 谢谢~rn#include rn#include rnrn#include "b_tree.h"rnrn#define BOOK_NO_MAX 100rn#define BOOK_NO_MIN 1rnrn//对图书的操作。B-Tree对于图书来说基本上是透明的。 rnint get_book_no()rnrn int book_no;rninp:printf("书号:");scanf("%d",&book_no);rn if((book_no>BOOK_NO_MAX)||(book_nokey[j]);rn printf("%d\t%d\t%d\t%s %s\n",node->book[j]->key,rn node->book[j]->current,rn node->book[j]->total,rn node->book[j]->author,rn node->book[j]->name);rn rn return 0;rnrnrnint info_book()rnrn int id,j,flag;rn NODE *tmp; rn rn id=get_book_no();rn rn tmp=search(id,root,tmp,&j,&flag);rn rn if(flag==0)printf("没有这种书。\n");return 1;rn info_head();rn info(tmp,j); rn rn return 0;rnrnrnint find_by_name()rnrn char name[40];rn int id,i,j,flag;rn NODE *tmp; rn rn printf("书名:");scanf("%s",name);rn info_head();rn for(i=BOOK_NO_MIN;ibook[j]->name,name))info(tmp,j);rn rn rn return 0;rnrnrnint find_by_author()rnrn char author[20];rn int id,i,j,flag;rn NODE *tmp; rn rn printf("著者:");scanf("%s",author);rn info_head();rn for(i=BOOK_NO_MIN;ibook[j]->author,author))info(tmp,j);rn rn rn return 0;rnrnrnint find_book()rnrn int c;rn printf("1-按书号;2-按书名;3-按作者;其他-返回\n");rn scanf("%d",&c);rn switch(c)rn rn case 1:info_book();break;rn case 2:find_by_name();break;rn case 3:find_by_author();break;rn default:break; rn rn return 0;rnrnrnint add_book()rn//可能会添加/删除节点。rnrn int flag=0;rn BOOK *tmp;rn NODE *ptr;rn int key,i;rn rn key=get_book_no();rn rn ptr=search(key,root,ptr,&i,&flag);rn rn if(flag!=1)rn //需要新增节点 rn rn if((tmp=malloc(sizeof(BOOK)))==NULL)exit(1);rn tmp->key=key;rn printf("书名:");scanf("%s",tmp->name);rn printf("著者:");scanf("%s",tmp->author);rn printf("数量:");scanf("%d",&tmp->total);rn tmp->current=tmp->total;rn add_node(tmp);rn else//无须新增节点 rn printf("数量:");scanf("%d",&key);rn ptr->book[i]->total+=key;rn ptr->book[i]->current+=key;rn rn rn return 0;rnrnrnint del_book()rn//只搜索,不会添加/删除节点。rnrn int id,n,j,flag;rn NODE *tmp;rn rn id=get_book_no();rn rn tmp=search(id,root,tmp,&j,&flag);rn if(flag==0)printf("没有这种书。\n");return 1;rn info_head();rn info(tmp,j);rn printf("要出库多少本? ");scanf("%d",&n);rn if(n>tmp->book[j]->current)printf("没有库存了。\n");return 1;rn tmp->book[j]->current-=n;rn rn return 0;rnrnrnint lent_book()rn//只搜索,不会添加/删除节点。rnrn int id,n,j,flag;rn NODE *tmp;rn rn id=get_book_no();rn rn tmp=search(id,root,tmp,&j,&flag);rn if(flag==0)printf("没有这种书。\n");return 1;rn info_head();rn info(tmp,j);rn printf("要借多少本? ");scanf("%d",&n);rn if(n>tmp->book[j]->current)printf("没有库存了。\n");return 1;rn tmp->book[j]->current-=n;rn rn return 0;rnrnrnint give_book()rn//只搜索,不会添加/删除节点。rnrn int id,n,j,flag;rn NODE *tmp;rn rn id=get_book_no();rn rn tmp=search(id,root,tmp,&j,&flag);rn if(flag==0)printf("没有这种书。\n");return 1;rn info_head();rn info(tmp,j);rn printf("要还多少本? ");scanf("%d",&n);rn rn if((n+tmp->book[j]->current)>tmp->book[j]->total)printf("数据错误。\n");return 1;rn tmp->book[j]->current+=n;rn rn return 0;rnrnrnint load_from_file()rnrn FILE *fp;rn int i,key,flag;rn BOOK *tmp;rn NODE *ptr;rn rn if((fp=fopen("data.txt","r"))==NULL)rn rn printf("cannot open file\n");rn return 1;rn rn rn init();rn while(!feof(fp))rn rn fscanf(fp,"%d",&key);rn ptr=search(key,root,ptr,&i,&flag);rn rn //需要新增节点 rn if((tmp=malloc(sizeof(BOOK)))==NULL)exit(1);rn tmp->key=key;rn fscanf(fp,"%d",&tmp->current);rn fscanf(fp,"%d",&tmp->total);rn fscanf(fp,"%s",tmp->author);rn fscanf(fp,"%s",tmp->name);rn rn add_node(tmp);rn rn rn fclose(fp);rnrnrnint save_to_file()rnrn FILE *fp;rn int i,j,flag=0;rn NODE *tmp;rn rn if((fp=fopen("data.txt","w"))==NULL)rn rn printf("cannot open file\n");rn return 1;rn rn rn for(i=BOOK_NO_MIN;ibook[j]->key,rn tmp->book[j]->current,rn tmp->book[j]->total,rn tmp->book[j]->author,rn tmp->book[j]->name);rn rn rn fclose(fp);rn rn return 0; rnrnrnrnint load_n_save()rnrn int c;rn printf("1-加载;2-存盘;其他-返回\n");rn scanf("%d",&c);rn switch(c)rn rn case 1:load_from_file();break;rn case 2:save_to_file();break;rn default:break; rn rn return 0;rnrnrnint shell()rnrn int cmd=-1;rn rn dorn printf("1-添加 2-删除 3-借书登记 4-还书登记 5-查找 9-加载&存盘 0-退出。\n> ");rn scanf("%d",&cmd);rn rn switch(cmd)rn rn case 1:add_book();break;rn case 2:del_book();break;rn case 3:lent_book();break;rn case 4:give_book();break;rn case 5:find_book();break;rn case 9:load_n_save();break;rn default:break;rn rn rn while(cmd!=0);rn return 0;rnrnrnint main(int argc, char *argv[])rnrn init();rn shell();rn rn system("PAUSE"); rn return 0;rnrn 论坛

没有更多推荐了,返回首页