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

📄 tsc.c

📁 傅立叶变换和小波变换是图像压缩的重要工具。该代大戏是利用小波变换进行图像压缩。
💻 C
字号:

#include <crblib/inc.h>
#include <time.h>
#include <windows.h>

#pragma comment(lib,"winmm.lib")

#include "tsc.h"

#ifdef _MSC_VER //{

void readTSC(ulong *hi)
{
ulong *lo = hi + 1;
	__asm 
	{
		rdtsc
		mov EBX,hi
		mov DWORD PTR [EBX],EDX
		mov EBX,lo
		mov DWORD PTR [EBX],EAX
	}
	return;
}

double diffTSChz(ulong *tsc1,ulong *tsc2)
{

 return	(tsc2[0] - tsc1[0])*4294967296.0 +
		(double)(tsc2[1] - tsc1[1]);

}

double readTSChz(void)
{
tsc_type tsc;
	readTSC(tsc);
return	(tsc[0]*4294967296.0 + (double)tsc[1]);
}

#else // }{ PC

void readTSC(ulong *hi)
{
	hi[0] = clock();
	hi[1] = 0;
}
double diffTSChz(ulong *tsc1,ulong *tsc2)
{
	return tsc2[0] - tsc1[0]; 
}

double readTSChz(void)
{
	return	clock();
}

#endif // } PC


typedef struct tscNode tscNode;
struct tscNode 
{
	tscNode *next;
	ulong tsc[2];
};
tscNode * head = NULL;

void pushTSC(void)
{
tscNode *tn;
	tn = new(tscNode);
	if ( !tn ) return;
	tn->next = head;
	head = tn;
	readTSC(tn->tsc);
}

double popTSC(void)
{
tscNode *tn;
ulong tsc[2];
	readTSC(tsc);
	if ( ! head ) return 0.0;
	tn = head;
	head = head->next;
return diffTSC(tn->tsc,tsc);
}

double popTSChz(void)
{
tscNode *tn;
ulong tsc[2];
	readTSC(tsc);
	if ( ! head ) return 0.0;
	tn = head;
	head = head->next;
return diffTSChz(tn->tsc,tsc);
}

double diffTSC(ulong *tsc1,ulong *tsc2)
{
return diffTSChz(tsc1,tsc2) * secondsPerTSC();
}

void showPopTSC(const char *tag,FILE * fp)
{
double time;

	time = popTSC();

	showTSC(tag,fp,time);
}

void showTSC(const char *tag,FILE * fp,double time)
{	
	fprintf(fp,"%s : %f secs\n",tag,time);
}

void showPopTSCper(FILE * fp,const char *tag,int items,const char *itemTag)
{
double time;

	time = popTSC();
	showTSCper(fp,tag,items,itemTag,time);
}

void showTSCper(FILE * fp,const char *tag,int items,const char *itemTag,double time)
{
double hz,per;

	hz = time * tscMHZ() * 1000000;
	per = time/(double)items;
	
	fprintf(fp,"%s : %f secs = %2.1f cycles / %s = ",tag,time,hz/items,itemTag);

	if ( per < 0.0001 ) 
	{
		fprintf(fp,"%d %ss /sec\n",(int)(1.0/per),itemTag);
	}
	else
	{
		fprintf(fp,"%f %ss /sec\n",(1.0/per),itemTag);
	}
}

#define TSC_REGISTRY_PATH	"SOFTWARE\\cbloom"
#define TSC_REGISTRY_VAL	"tscMHZ"

bool RegistryGetValue(const char * path,const char * file,int * pValue)
{
	HKEY hKey;
	bool result;
	DWORD type;
	DWORD size;
	char work[80];

	if ( RegOpenKeyEx(HKEY_LOCAL_MACHINE,path,0,KEY_QUERY_VALUE,&hKey)
		 != ERROR_SUCCESS )
	{
		return false;
	}

	// Set the value for the given name as a binary value

	result = RegQueryValueEx
				(
					hKey,
					file,
					0,
					&type,
					//(BYTE *) pValue,
					(BYTE *)work,
					&size
				) == ERROR_SUCCESS;
 
	RegCloseKey (hKey);

	if ( result )
	{
		*pValue = atoi(work);
	}

	return result;
}

bool RegistrySetValue(const char * path,const char * file,int value)
{
	HKEY hKey;
	bool result;
	char work[80];

	if ( RegOpenKeyEx(HKEY_LOCAL_MACHINE,path,0,KEY_ALL_ACCESS,&hKey)
		 != ERROR_SUCCESS )
	{
		// Create the key.  The valueName, if given, is ignored.
		DWORD dwDisposition;
		if ( RegCreateKeyEx
						(
							HKEY_LOCAL_MACHINE,
							path,
							0,
							"",
							REG_OPTION_NON_VOLATILE,
							KEY_ALL_ACCESS,
							NULL,
							&hKey,
							&dwDisposition
						) != ERROR_SUCCESS )
		{
			return false;
		}
	}

	// Set the value for the given name as a binary value

	/*
	result = RegSetValueEx
				(
					hKey,
					file,
					0,
					REG_BINARY,
					(CONST BYTE *) &value,
					sizeof(value)
				) == ERROR_SUCCESS;
	*/

	itoa(value,work,10);

	result = RegSetValueEx
				(
					hKey,
					file,
					0,
					REG_SZ,
					(CONST BYTE *) work,
					strlen(work)+1
				) == ERROR_SUCCESS;

	RegCloseKey (hKey);

	return result;
}

static double secondsPerClock = 0.0f;
static bool haveSecondsPerClock = false;
static int TSC_MHZ = 0;

double secondsPerTSC(void)
{
double clocksPerSec,MHZ;

	if ( haveSecondsPerClock )
	{
		return secondsPerClock;
	}

	if ( ! RegistryGetValue(TSC_REGISTRY_PATH,TSC_REGISTRY_VAL,&TSC_MHZ) )
	{
		DWORD clock1,clock2;
		tsc_type tsc1,tsc2;
		double secondsElapsed;
		volatile int i,j;

		#define SECONDS_TO_TEST	(10)

		fprintf(stderr,"Calibrating TSC for %d seconds!\n",SECONDS_TO_TEST);

		clock1 = timeGetTime();
		readTSC(tsc1);
		i = j = 0;
		while( (timeGetTime() - clock1) < 1000*SECONDS_TO_TEST )
		{
			// on lap-tops you have to do some real math here 
			//	to prevent the cpu from sleeping !!
			//Sleep(1);
			i++;
			j += rand();
		}
		clock2 = timeGetTime();
		readTSC(tsc2);
		secondsElapsed = (clock2 - clock1)/1000.0;
		clocksPerSec = diffTSChz(tsc1,tsc2) / secondsElapsed;

		MHZ = clocksPerSec / (1000000.0);

		fprintf(stderr,"Measured MHZ before rounding : %f\n",MHZ);

		// check for common errors
		//	round to nearest multiple of 50 or 83.33
		{
			int Z50,Z83;
			Z50 = ((int)((MHZ + 25)/50))*50; // round to the nearest fifty
			Z83 = ((int)(((MHZ + 41)*12)/1000))*1000/12; // round to the nearest 83.333 == 1000/12
			if ( ABS((double)Z50 - MHZ) < 14 )
				MHZ = Z50;
			else if ( ABS((double)Z83 - MHZ) < 14 )
				MHZ = Z83;
			else
				MHZ = ((int)((MHZ + 5)/10))*10; // round to the nearest ten

			TSC_MHZ = (int) MHZ;
		}
	
		fprintf(stderr,"Storing MHZ after rounding : %d\n",TSC_MHZ);

		RegistrySetValue(TSC_REGISTRY_PATH,TSC_REGISTRY_VAL,TSC_MHZ);
	}

	clocksPerSec  = TSC_MHZ * (1000000.0);

	haveSecondsPerClock = true;
	secondsPerClock = 1.0f / clocksPerSec;

return secondsPerClock;
}

double timeTSC(void)
{
double time;
	time = readTSChz();
return time * secondsPerTSC();
}

int tscMHZ(void)
{
	secondsPerTSC();
return TSC_MHZ;
}

⌨️ 快捷键说明

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