⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 docpu.h

📁 代码优化,有效使用内存,透视优化技术,对比优化方法,如果你在追求代码效率的最大化,该资源你不能不读.
💻 H
📖 第 1 页 / 共 2 页
字号:
#define	A1_OUT(s)			L1_OUT(s)

//		The A1_OUT macro outputs the s string and execution time of the program fragment
// labeled by the val  checkpoint in relation to the exeution time of the fragment labeled
// by the base checkpoint.
#define	Ax_OUT(s,base,val)	Lx_OUT(s, Ax_GET(base), Ax_GET(val))


//		The A_LIST_ITER prints all results for measurement of the 
// t checkpoint
#define A_LIST_ITER(t)		printf("LIST_ITER {\n");						\
							for(DoCPU_tmp=0;DoCPU_tmp<A_NITER;DoCPU_tmp++)	\
								printf("\t%d\n",DoCPU_buff[t][DoCPU_tmp]);	\
							printf("} LIST_ITER\n");


//		The  A_LIST_ITER_AS_TABLE  prints all measurment results for the
// program fragment labeled by the t checkpoint and generates
// a table suitable for importing into MS Graph
#define A_LIST_ITER_AS_TABLE(s,buf)											\
							printf(s);										\
							for(DoCPU_tmp=0;DoCPU_tmp<A_NITER;DoCPU_tmp++)	\
								printf("\t%d",buf[DoCPU_tmp]);				\
								printf("\n");
/*
// #define	Lx_OUTx(s,buf_base,buf_val,x_factor)\
// printf("%s : %d%%\n",s,100*(cycle_mid(DoCPU_buff[buf_val],0)/x_factor)/
// (cycle_mid(DoCPU_buff[buf_base],0)/x_factor));
// #define	Lx_OUT_DEBUG(s,buf_base,buf_val) printf("%s : %d%%, %d%%\n",s,cycle_mid(DoCPU_buff[buf_val],0),cycle_mid(DoCPU_buff[buf_base],0));
*/


// MACROS FOR DISPLAYING THE PROGRESS
// ======================================

//		Macro displaying the rotating "propeller"
#define VVV	if (DoCPU_vcp >= strlen(DoCPU_v))	DoCPU_vcp = 0;				\
			sprintf(DoCPU_s,"\rDoCPU:%c\r",DoCPU_v[DoCPU_vcp]);				\
			PRINT(DoCPU_s); DoCPU_vcp++;

//		Macro displaying the current progress in percents
#define PRINT_PROGRESS(x)	sprintf(DoCPU_s,"\rProgress : %3d%%\r",(x));	\
							PRINT(DoCPU_s);


// FUNCTION FOR DISPLAYING DIAGRAMS "ON THE fLY"
// ---------------------------------------------
// ARG:
//		size	-	size of the diagram bar
//
//		n_sym	-	number of characters within the string (NULL == 80)
//
//		max		-	maximum value of size.
//					==  0 : max is equal to the doubled value of the first size
//					== -1 : resetting the previous value of form_factor and returning
//
//		nl		-	==  0 : proportional scale
//					==  1 : logarithmic scale
void online_graph(int size, int n_sym, int max, int nl)
{
	int		a;
	int		form_factor;
	static	graph_size = 0;

	// resetting graph_size to zero
	if (max == -1) { graph_size = 0; return; }

	// calculating graph_size by the first size value
	if ((!max) && (!graph_size)) graph_size = size * 2;

	// calculating the diagram length
	if (!n_sym) n_sym = MAX_GRAPH_LEN;

	// calculating the form_factor
	if (!max) form_factor = graph_size / n_sym;
		else
	form_factor = max / n_sym;

	// special processing for logarithmic string
	if (nl)
	{
		size = 10*log(size);
		form_factor=1;
	}

	if (!form_factor) form_factor = 1;

	size /= form_factor;
	// displaying the diagram
	for (a = 0; a < size; a++)
	{
		if (a >= (n_sym-3))
		{									// diagram limits are exceeded
			if (size > (n_sym-3)*3) printf(">");
			if (size > (n_sym-3)*2)	printf(">");
			if (size > (n_sym-3)*1)	printf(">");
			
			
			break;
		}
		printf(GRAPH_CHAR);
	}
	printf("\n");
}

//		Macro for quick call to online_graph with default arguments
#define GRAPH(a) online_graph(a,0,0,0);

//		Macros for initializing online_graph
#define RE_GRAPH online_graph(0,0,-1,0);


/*----------------------------------------------------------------------------
 *
 *										INPUT
 *
----------------------------------------------------------------------------*/

// reading memory area. Is it needed?
#define A_READ(p, size_p)	for(DoCPU_tmp=0; DoCPU_tmp < size_p; DoCPU_tmp += sizeof(int))\
													DoCPU_tmp1+=((int *)(p+DoCPU_tmp))[0];




/*----------------------------------------------------------------------------

						FUNCTIONS FOR WORKING WITH MEMORY AND CACHE

----------------------------------------------------------------------------*/

//		The _malloc32 macro allocates x bytes of memory and guarantees that the allocated block
// will start from the address that is a multiple of 32
#define	_malloc32(x)	(( (((int) malloc((x)+0x20)) + 0x20) & 0xFFFFFFE0  ));


//		The _align32 macro aligns the p pointer by address that is a multiple of 32 bytes
#define	_align32(p)		(( (((int) (p)) + 0x20) & 0xFFFFFFE0  ));


//		The CLEAR_L2_CACHE  macro fill L2 cache with garbage, thus
// flushing the data that was written into it earlier.
int CLEAR_L2_CACHE()
{
	int a;
	int x = 0;
	
	if (!p_cache) p_cache = (int *) malloc(_NORMAL);

	for (a = 0; a<_NORMAL; a++)
		x += *(int *)((int)p_cache+a);
	
	return x;
}



int CLEAR_ALL()
{
		// !!!UNDER CONSTRUCTION!!!
		return 0;
}


//		This macro flushes store buffers on P-III 
void _DoCPU_a_fflush()
{
#ifdef __FLUSH__
	_DoCPU_a_flush();
#endif
}



#define RM 	for(DoCPU_tmp = 0; DoCPU_tmp < 10; DoCPU_tmp++) DoCPU_float_tmp+=0.99;



/*----------------------------------------------------------------------------

								SERVICE FUNCTIONS

----------------------------------------------------------------------------*/

// * FUNC: int getargv(char *arg_name, char *arg_val)
// * Function for checking if the argument keys are present and received
//
//		If the arg_name argument is specified in the command line,
// the function returns non-negative value;
//
//		If the arg_name argument is missing from the command line
// (or, if its length exceeds MAX_STR_LEN), the function returns -1;
//
//		If the argument has a key,   separated from it by a colon
// (something like "/XXX:666"), its string value is returned in arg_val
// provided that arg_val is not equal to zero;
//
//		If  arg_val==NULL this means that the argument's key is not needed;
//
//		If the key is present, the function also attempts to return its numeric
// value (received from atol);
//
//		NOTE: If the function returns 0, the situation is ambiguous: either
// the argument has no key at all, or the key is not a numeric value, or the key
// is actually equal to zero. If this is the case, check the contents of 
// arg_val to clarify the situation
int getargv(char *arg_name, char *arg_val)
{
	int				a;
	int*			p;
	unsigned int	c;
	
	char			buf_arg[MAX_STR_LEN];
	char			buf_val[MAX_STR_LEN];

	#ifndef __argv		
		char** __argv;
		int __argc=0;
	#endif

	if (!arg_name) return -1;

	if (arg_val) arg_val[0] = 0;	// Initialization

	// Testing all arguments
	for (a = 1; a < __argc; a++)
	{
		if (strlen(__argv[a]) >= MAX_STR_LEN) return -1;

		// Parsing the argument syntax and copying its name into buf_arg
		for (c=0;c!=(1+strlen(__argv[a]));c++)
		{
			if (__argv[a][c] == ':') { buf_arg[c] = 0; break; }
				buf_arg[c] = __argv[a][c];
		}
		
		// Copying the key (if there is any) into buf_val
		if (__argv[a][c] == ':') strcpy(buf_val, &__argv[a][c +1]); else buf_val[0] = 0;

		// If this is the argument that is needed, then copy its value into arg_val
		if (!strcmp(arg_name,buf_arg))
		{
			if (arg_val) strcpy(arg_val,buf_val);
			return atol(buf_val);
		}
	}
	return -1;
}

//		The IFHELP macro displays the s string provided that the "/?" 
// command-line option is specified, and terminates the program execution
#define	IFHELP(s)	if (getargv("/?",0)!=-1){ PRINT(_TEXT(s)); return 0; }

//		The  GETARGV   is the "wrapper" for the getargv function.
// If the s  key is present in the command line, it stores the key value into the
// val variable. If the s key is not present in the command line, the val variable
// does not change.
#define	GETARGV(s,val)	DoCPU_tmp=getargv(s,NULL);							\
						if (DoCPU_tmp!=-1) val=DoCPU_tmp;

//#define A_FLUSH _DoCPU_a_flush();
//#define A_FFLUSH _DoCPU_a_fflush();
//#define A_WAIT  Sleep(TIME_TO_WAIT);


/*----------------------------------------------------------------------------
 *
 *						PROFILER KERNEL FUNCTIONS
 *
----------------------------------------------------------------------------*/
int*	A0(void* x)
{
		Sleep(100);
		return DoCPU(x);
}


/*----------------------------------------------------------------------------
 *
 *						SERVICE FUNCTIONS OF THE PROFILER KERNEL
 *
----------------------------------------------------------------------------*/
// This function returns the clock frequency of the processor in MHz
int GetCPUclock(void)
{
	#define to_time 1

	int				tmp;
	unsigned int	t;
	volatile		time_t timer;

	tmp = getargv("$Fcpu",0);

	if (tmp <= 0)
	{
		if (!(tmp=CPU_CLOCK))
		{
			timer = time(NULL);
			while(timer == time(NULL));
			timer = time(NULL);

			A1(&t);
				while( timer+to_time > time(NULL));
			t=A2(&t);

			tmp=((double)t) / ((double)1000000) / ((double)to_time);

			CPU_CLOCK=tmp;
		}
	}
	
	if (getargv("$DEBUG.print.Fcpu",0)!=-1) printf(">DEBUG:Fcpu=%d\n",tmp);
	return tmp;
}

// This function converts clocks into seconds
float cpu2timeu(unsigned int ticks, int tt)
{
	if (tt)
		return ((float )ticks)/CLOCKS_PER_SEC;

	if (!CPU_CLOCK) CPU_CLOCK=GetCPUclock();
		return ((float )ticks)/CPU_CLOCK/1000000;
}


#ifdef _NORDTSC
	float cpu2time(int ticks)
	{
		return cpu2timeu(ticks, 0);
		
	}
#else
	float cpu2time(int ticks)
	{
		return cpu2timeu(ticks, 1);
	}
#endif


/*----------------------------------------------------------------------------
 *
 *						KERNEL FUNCTIONS FOR PROCESSING THE RESULTS
 *
----------------------------------------------------------------------------*/
int cycle_min(int *buff, int n_buff)
{
	int a, tmp;
	if (!n_buff)	n_buff = DoCPU_BUFF_SIZE;

	tmp = buff[0];
	for(a = 0; a < n_buff; a++)
		if (buff[a] < tmp) tmp = buff[a];
	return tmp;
}

int cycle_max(int *buff, int n_buff)
{
	int a, tmp;
	if (!n_buff)	n_buff = DoCPU_BUFF_SIZE;
	
	tmp = buff[0];
	for(a = 0; a < n_buff; a++)
		if (buff[a] > tmp) tmp = buff[a];

	return tmp;
}


	int _compare(unsigned int *arg1, unsigned int *arg2 )
	{
		if (*arg2 >= *arg1) return -1;
		// else 
		return +1;
	}

unsigned int cycle_mid(unsigned int *buff, int nbuff)
{
	int a, xa = 0;
	if (!nbuff) nbuff = A_NITER;

	// 锐觌

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -