Newsgroup: it.comp.programmare.win32
Titolo: Clock del processore?

Come fare a determinare - in windows - la velocità del processore con una
ragionevole approssimazione? Sto facendo un emulatore, e mi serve sapere di
quanto sono piu' veloce del processore emulato per sincronizzarmi.
Saluti.
Zello

Qual'č il tuo indirizzo di e-mail? Volevo mandarti il codice di
esempio, ma non č quello fornito al newsgroup ....

Anche io ti ho mandato del codice, ma mi e' tornata indietro la mail :-)

 esempio, ma non è quello fornito al newsgroup ....
Non è che mi potresti mandare questo codice anche a me ?
Grazie
    Riccardo (r.pellegrini(at)
info01.it
)

 ha scritto nel messaggio
news:3b553966...@news.galactica.it...


Puoi mandare il codice anche a me????
Grazie 1000,
                                       Jorge

 esempio, ma non è quello fornito al newsgroup ....
ma è così complesso? pensavo che fosse una varabile ambientale o nel
registro tipo
x86 blabla family model stepping blabla ~xxx Mhz.
ciao

ragionevole approssimazione? 
/***************************************************************************\
File:					cpuid.cpp
Design:				Davide Quack 
Codifica:			Davide Quack
Bench per testare il tipo di processore
Versione 0.1
	Inizio stesura:	12/04/1999
	Ultime modifiche:	21/04/1999
Versione 0.3
	Inizio stesura:	05/09/2000
	Ultime modifiche:	05/09/2000
Versione 0.4.0
	Inizio stesura:	07/10/2000
	Ultime modifiche:	07/10/2000
Software Open Source posto sotto licenza GPL
\***************************************************************************/
/***************************************************************************\
	Funzioni del file
int main(int argc, char* argv[])
\***************************************************************************/
#ifdef WIN32 
#include <memory.h>
#include <windows.h>
#endif
#include <direct.h>
#include <stdio.h>
namespace q_rdtsc
{
	union int3264
	{ 
		struct int32x2
		{
			unsigned __int32 lw;
			unsigned __int32 hi;
		}; 
		unsigned __int64 i64;
		int32x2 i32;
	};
}
void rdtsc(void)
{
	unsigned int conteggio1 = 0;
	unsigned int conteggio2 = 0;
	unsigned int conteggio3 = 0;
	unsigned int conteggio4 = 0;
	unsigned int tempoinizio= 0;
	unsigned int tempofine	= 0;
	unsigned int massimo	= 0;
	unsigned int cicli = 10;
	using namespace q_rdtsc;
	int3264	prima;
	int3264	dopo;
 
	//misurazione frequenza vera
#ifdef WIN32 
	Sleep(0);
#endif
#ifdef POSIX
	sleep(0);
#endif
 
	__asm
	{
		rdtsc	; contatore a 64 bit 
		mov	prima.i32.lw, eax; memorizzo i 32 bit meno significativi
del contatore
		mov	prima.i32.hi, edx; memorizzo i 32 bit piu' significativi
del contatore
	}
#ifdef WIN32
	//millisecondi
	tempoinizio = GetTickCount();
#endif
#ifdef POSIX
	//secondi
	tempoinizio = time();
#endif
	//dormo 3 secondi
#ifdef WIN32 
	Sleep(3000);
#endif
#ifdef POSIX
	sleep(3000);
#endif
	__asm
	{
		rdtsc	; contatore a 64 bit 
		mov	dopo.i32.lw, eax; memorizzo i 32 bit meno significativi
del contatore
		mov	dopo.i32.hi, edx; memorizzo i 32 bit piu' significativi
del contatore
	}
#ifdef WIN32
	//millisecondi
	tempofine = GetTickCount();
#endif
#ifdef POSIX
	//secondi
	tempofine = time();
#endif
	tempofine -= tempoinizio; //tempo trascorso
	prima.i64 = dopo.i64 - prima.i64; //conteggi effettuati
#ifdef WIN32
	conteggio1 = __int32( prima.i64 / __int64(tempofine) ) / 1000;
#endif
#ifdef POSIX
	conteggio1 = __int32(prima.i64 / __int64(tempofine) );
#endif
	printf("frequenza reale del processore %i Mhz\n", conteggio1);
	//misurazione frequenza apparente
	while(--cicli)
	{
		//rilascio il tempo del thread
#ifdef WIN32 
		Sleep(0);
#endif
#ifdef POSIX
		sleep(0);
#endif
		__asm
		{
			rdtsc						; contatore a 64 bit 
			mov	conteggio1, eax; memorizzo i 32 bit meno significativi
del contatore
			mov	conteggio2, edx; memorizzo i 32 bit piu' significativi
del contatore
		}
#ifdef WIN32
		//millisecondi
		tempoinizio = GetTickCount();
#endif
#ifdef POSIX
		//secondi
		tempoinizio = time();
#endif
		__asm
		{
			mov	ecx, 10000000	; inizializzo il ciclo con un milione
	startloop:
			//loop	startloop	; istruzione lunga come la fame
			dec	ecx				; decremento il contatore
			jnz	startloop		; se diverso da zero il flag di zero
resto nel ciclo
			rdtsc						; richiamo il contatore
			mov	conteggio3, eax; memorizzo i 32 bit meno significativi
del contatore
			mov	conteggio4, edx; memorizzo i 32 bit piu' significativi
del contatore
		}
#ifdef WIN32
		//millisecondi
		tempofine = GetTickCount();
#endif
#ifdef POSIX
		//secondi
		tempofine = time();
#endif
 
		//ho usato la DWORD piu' significativa del contatore?
		conteggio4 -= conteggio2;
		if(conteggio4)
		{
			//male, lascio perdere per semplicita' questo giro
			continue;
		}
		//numero di conteggi in un ciclo
		conteggio3 -= conteggio1;
		//durata di un ciclo
		tempofine -= tempoinizio;
		//processore eccessivamente veloce?
		if(tempofine)
		{
			//numero di istruzioni processate al secondo
			//ATTENZIONE - le istruzioni sono due a loop
#ifdef WIN32
			conteggio2 = (conteggio3 / (tempofine * 500));
#endif
#ifdef POSIX
			conteggio2 = ((conteggio3 * 2) / tempofine);
#endif
			if(massimo < conteggio2)
			{
				//prestazione massima
				massimo = conteggio2;
			}
		}
	}
	printf("frequenza apparente del processore in un loop stretto %i
Mhz\n\n", massimo);
	return;
}
void cpuid(void)
{
	const unsigned int MMX_FEATURE_BIT		= 0x00800000;
	const unsigned int SSE_FEATURE_BIT		= 0x02000000;
	const unsigned int SSE2_FEATURE_BIT		= 0x04000000;
	const unsigned int TREDNOW_FEATURE_BIT	= 0x80000000;
	unsigned int regEAX;
	unsigned int regEBX;
	unsigned int regECX;
	unsigned int regEDX;
	unsigned int regAMD = 0;
	unsigned int family;
	unsigned int model;
	bool	step1 = false, step2 = false, step3 = false;
	char sCPU[16];
	memset(sCPU, 0, sizeof(sCPU));
 
	//step 0, voglio sapere il produttore
	__asm
	{
		;//salvo il valore dei registri che modifichero'
		push	eax 
		push	ebx 
		push	ecx 
		push	edx 
		mov	eax, 0
		cpuid
		//salvo il risultato
		mov 	regEAX, eax
		mov 	regEBX, ebx
		mov 	regECX, ecx
		mov 	regEDX, edx
		;//ripristino i valori dei registri che verranno modificati
		pop	edx 
		pop	ecx 
		pop	ebx 
		pop	eax 
	}
	//quante chiamate diverse posso fare con l'istruzione CPUID?
	switch(regEAX)
	{
	case 2:
		step2 = true;
	case 1:
		step1 = true;
		break;
	default:
		step3 = true;
		break;
	}
	//stringa del produttore ritornata
	sCPU[ 0] = (char)((regEBX >>  0) & 0xFF);
	sCPU[ 1] = (char)((regEBX >>  8) & 0xFF);
	sCPU[ 2] = (char)((regEBX >> 16) & 0xFF);
	sCPU[ 3] = (char)((regEBX >> 24) & 0xFF);
	sCPU[ 4] = (char)((regEDX >>  0) & 0xFF);
	sCPU[ 5] = (char)((regEDX >>  8) & 0xFF);
	sCPU[ 6] = (char)((regEDX >> 16) & 0xFF);
	sCPU[ 7] = (char)((regEDX >> 24) & 0xFF);
	sCPU[ 8] = (char)((regECX >>  0) & 0xFF);
	sCPU[ 9] = (char)((regECX >>  8) & 0xFF);
	sCPU[10] = (char)((regECX >> 16) & 0xFF);
	sCPU[11] = (char)((regECX >> 24) & 0xFF);
	printf("Vendor identification string = %s \n", sCPU);
 
	if(step1)
	{
		const int maskStepping = 0xF;
		const int shiftStepping = 0;
		const int maskModel = 0xF0;
		const int shiftModel = 4;
		const int maskFamily = 0xF00;
		const int shiftFamily = 8;
		const int maskType = 0x3000;
		const int shiftType = 12;
		int valore;
		//step 1 voglio sapere tutto sul processore
		__asm
		{	
			;//salvo il valore dei registri che modifichero'
			push	eax 
			push	ebx 
			push	ecx 
			push	edx 
			mov	eax, 1
			cpuid
			;//salvo il risultato
			mov 	regEAX, eax
			mov 	regEDX, edx
			;// AMD specials
			mov eax,80000000h
			cpuid
			cmp eax,80000000h
			jc notamd
			mov eax,80000001h
			cpuid
			mov regAMD,edx
notamd:
			;//ripristino i valori dei registri che verranno modificati
			pop	edx 
			pop	ecx 
			pop	ebx 
			pop	eax 
		}
		valore = ((regEAX & maskType) >> shiftType);
		printf("Type     = %i\n", valore );
		family = ((regEAX & maskFamily) >> shiftFamily);
		printf("Family   = %i\n", family );
		model = ((regEAX & maskModel) >> shiftModel);
		printf("Model    = %i\n", model );
		printf("Stepping = %i\n\n", ((regEAX & maskStepping) >>
shiftStepping) );
		switch(valore)
		{
		case 0:
			printf("(Original OEM Processor)\n");
			break;
		case 1:
			printf("(Intel OverDrive Processor)\n");
			break;
		case 2:
			printf("(Dual Processor)\n");
			break;
		case 3:		 
			printf("(Mistero Intel)\n");
			break;
		}
		if (!strncmp("AuthenticAMD", sCPU, 12))
		{
			switch (family) // extract family code
			{
			case 4: // Am486/AM5x86
				printf("AMD Am486\n");
				break;
			case 5: // K6
				switch (model) // extract model code
				{
				case 0:
				case 1:
				case 2:
				case 3: 
					printf("AMD K5\n");
					break;
				case 4:
					break;  // Not really used
				case 5:
					break;  // Not really used
				case 6:
				case 7: 
					printf("AMD K6\n");
					break;
				case 8:
					printf("AMD K6-2\n");
					break;
				case 9: 
				case 10:
				case 11:
				case 12:
				case 13:
				case 14:
				case 15:
					printf("AMD K6-3\n");
					break;
				default:
					printf("AMD Unknown\n");
				}
				break;
			case 6: // Athlon
				switch(model)  // No model numbers are currently defined
				{
				case 1:
				default:
					printf("AMD ATHLON\n");
				}
				break;
			}
		} else if ( !strncmp("GenuineIntel", sCPU, 12))
		{
			switch (family) // extract family code
			{
			case 4:
            switch (model) // extract model code
            {
            case 0:
            case 1:
					printf("INTEL 486DX\n");
					break;
            case 2:
					printf("INTEL 486SX\n");
					break;
            case 3:
					printf("INTEL 486DX2\n");
					break;
            case 4:
					printf("INTEL 486SL\n");
					break;
            case 5:
					printf("INTEL 486SX2\n");
					break;
            case 7:
					printf("INTEL 486DX2E\n");
					break;
            case 8:
					printf("INTEL 486DX4\n");
					break;
            default:
					printf("INTEL Unknown\n");
            }
            break;
			case 5:
            switch (model) // extract model code
            {
            case 1:
            case 2:
            case 3:
					printf("INTEL Pentium\n");
					break;
            case 4:
					printf("INTEL Pentium-MMX\n");
					break;
            default:
					printf("INTEL Unknown\n");
            }
            break;
			case 6:
            switch (model) // extract model code
            {
            case 1:
					printf("INTEL Pentium-Pro\n");
					break;
            case 3:
					printf("INTEL Pentium-II\n"); break;
            case 5:
					printf("INTEL Pentium-II\n");
					break;  // actual differentiation depends on cache
settings
            case 6:
					printf("INTEL Celeron\n");
					break;
            case 7:
					printf("INTEL Pentium-III\n");
					break;  // actual differentiation depends on cache
settings
            default:
					printf("INTEL Unknown\n");
            }
            break;
			}
		} else if ( !strncmp("CyrixInstead", sCPU, 12))
		{
			printf("Cyrix Unknown\n");
		} else if ( !strncmp("CentaurHauls", sCPU,12))
		{
			printf("Centaur Unknown\n");
		}
		printf("\n");
		//testo i bit delle caratteristiche
		printf("FPU on chip\n");
		if(regEDX & 0x1)
		{
			printf("Presente il coprocessore integrato\n");
		}
		else
		{
			printf("Non presente il coprocessore integrato\n");
		}
		printf("\n");
		printf("Virtual 8086 Mode Enhancement\n");
		if(regEDX & 0x2)
		{
			printf("8086 virtualizzabile via hardware\n");
		}
		else
 		{
			printf("8086 non virtualizzabile via hardware\n");
		}
		printf("(Paranoia della retrocompatibilita' a tutti i
costi)\n");
		printf("\n");
		printf("I/O Breakpoints\n");
		if(regEDX & 0x4)
		{
			printf("Il processore supporta le istruzioni per il
debugging\n");
		}
		else
		{
			printf("Il processore non supporta le istruzioni per il
debugging\n");
		}
		printf("\n");
		printf("Page Size Extensions\n");
		if(regEDX & 0x8)
		{
			printf("Il processore puo' allocare pagine di 4Mb\n");
		}
		else
		{
			printf("Il processore non puo' allocare pagine di 4Mb\n");
		}
		printf("(Ufficiosamente usate dal kernel di Linux e NT)\n");
		printf("\n");
		printf("Time Stamp Counter\n");
		if(regEDX & 0x10)
		{
			printf("Il processore ha il contatore con il numero di cicli
di clock\n");
		}
		else
		{
			printf("Il processore non ha il contatore con il numero di
cicli di clock\n");
		}
		printf("(Impossibile avere un contatore piu' veloce!)\n");
		printf("\n");
		printf("RDMSR and WRMSR Support\n");
		if(regEDX & 0x20)
		{
			printf("Presenti istruzioni a ring 0 per il monitoraggio
delle eccezioni\n");
		}
		else
		{
			printf("Non presenti istruzioni a ring 0 per il monitoraggio
delle eccezioni\n");
		}
		printf("(Non mi e' chiaro il loro uso in un S.O. reale)\n");
		printf("\n");
		printf("Physical Address Extensions\n");
		if(regEDX & 0x40)
		{
			printf("Il processore supporta un indirizzamento della
memoria oltre i 32 bit\n");
		}
		else
		{
			printf("Il processore non supporta un indirizzamento della
memoria oltre i 32 bit\n");
		}
		printf("(Gia' il PentiumPro permetteva di indirizzare oltre 4GB
di memoria)\n");
		printf("\n");
		printf("Machine Check Exception\n");
		if(regEDX & 0x80)
		{
			printf("E' possibile per il S.O. gestire le eccezioni
hardware\n");
		}
		else
		{
			printf("Il processore non permette al S.O. di gestire le
eccezioni hardware\n");
		}
		printf("(Richiesta dai S.O. con gestione strutturata delle
eccezioni)\n");
		printf("\n");
		printf("CMPXCHG8B Instruction - Compare and Exchange 8
Bytes\n");
		if(regEDX & 0x100)
		{
			printf("Presente instruzione atomica a 64 bit per comparare
valori tra registri\n");
		}
		else
		{
			printf("Non presente instruzione atomica a 64 bit per
comparare valori tra registri\n");
		}
		printf("(Forse una richiesta strana dei progettisti di NT per
simulare S.O. 64 bit)\n");
		printf("\n");
		printf("APIC on Chip\n");
		if(regEDX & 0x200)
		{
			printf("Presente nel processore un Advanced Programmable
Interrupt Controller\n");
		}
		else
		{
			printf("Non presente nel processore un Advanced Programmable
Interrupt Controller\n");
		}
		printf("(Necessario per i sistemi multiprocessore)\n");
		printf("\n");
		printf("Memory Type Range Request\n");
		if(regEDX & 0x1000)
		{
			printf("Presenti istruzioni a ring 0 per la gestione delle
cache\n");
		}
		else
		{
			printf("Non presenti istruzioni a ring 0 per la gestione
delle cache\n");
		}
		printf("\n");
		printf("PTE Global Bit\n");
		if(regEDX & 0x2000)
		{
			printf("Possibilita' di abilitare il bit di globale in PTDE e
PTE\n");
		}
		else
		{
			printf("Possibilita' di abilitare il bit di globale in PTDE e
PTE\n");
		}
		printf("(Grazie ad esso il kernel NT e' posto in una zona
coindivisa nella TBL)\n");
		printf("\n");
		printf("Machine Check Archtecture\n");
		if(regEDX & 0x4000)
		{
			printf("Possibilita' di gestire gli errori sulla memoria\n");
		}
		else
		{
			printf("Impossibilita' di gestire gli errori sulla
memoria\n");
		}
		printf("(Esempio d'errori gestiti: hardware, system bus, ECC,
parity, cache, TLB)\n");
		printf("\n");
		printf("Condizional Move/Compare Instruction\n");
		if(regEDX & 0x8000)
		{
			printf("Supporto per le istruzioni condizionato di
caricamento in memoria\n");
		}
		else
		{
			printf("Nessun supporto per le istruzioni condizionato di
caricamento in memoria\n");
		}
		printf("(Chi ha programmato sui PLC Siemens (alias ciofeche) sa
cosa sono)\n");
		printf("\nMMX - Multi Media eXtension\n");
		if(regEDX & MMX_FEATURE_BIT)
		{
			printf("Supporto per le istruzioni MMX\n");
		}
		else
		{
			printf("Nessun supporto per le istruzioni MMX\n");
		}
		printf("\n3DNOW - Estensioni multimediali di AMD\n");
		if(regAMD & TREDNOW_FEATURE_BIT)
		{
			printf("Supporto per le istruzioni 3DNOW\n");
		}
		else
		{
			printf("Nessun supporto per le istruzioni 3DNOW\n");
		}
		printf("\nSSE - Estensioni multimediali SSE\n");
		if(regEDX & SSE_FEATURE_BIT)
		{
			printf("Supporto per le istruzioni SSE\n");
		}
		else
		{
			printf("Nessun supporto per le istruzioni SSE\n");
		}
		printf("\nSSE2 - Estensioni multimediali SSE2\n");
		if(regEDX & SSE2_FEATURE_BIT)
		{
			printf("Supporto per le istruzioni SSE2\n");
		}
		else
		{
			printf("Nessun supporto per le istruzioni SSE2\n");
		}
		printf("\n");
	}
	if(step2)
	{
		__asm
		{
			;//salvo il valore dei registri che modifichero'
			push	eax 
			push	ebx 
			push	ecx 
			push	edx 
			;//il perche' duplicazione e' in un commento successivo
			mov	eax, 2
			cpuid
			mov	eax, 2
			cpuid
			mov	eax, 2
			cpuid
 
			//salvo il risultato
			mov 	regEAX, eax
			mov 	regEBX, ebx
			mov 	regECX, ecx
			mov 	regEDX, edx
			;//ripristino i valori dei registri che verranno modificati
			pop	edx 
			pop	ecx 
			pop	ebx 
			pop	eax 
		}
		memset(sCPU, 0, sizeof(sCPU));
		//scompongo il risultato in byte
		//dato valido?
		if( !(regEAX & 0x70000000) )
		{
			sCPU[ 0] = (char)((regEAX >>  0) & 0xFF);
			sCPU[ 1] = (char)((regEAX >>  8) & 0xFF);
			sCPU[ 2] = (char)((regEAX >> 16) & 0xFF);
			sCPU[ 3] = (char)((regEAX >> 24) & 0xFF);
		}
		if( !(regEBX & 0x70000000) )
		{
			sCPU[ 4] = (char)((regEBX >>  0) & 0xFF);
			sCPU[ 5] = (char)((regEBX >>  8) & 0xFF);
			sCPU[ 6] = (char)((regEBX >> 16) & 0xFF);
			sCPU[ 7] = (char)((regEBX >> 24) & 0xFF);
		}
		if( !(regECX & 0x70000000) )
		{
			sCPU[ 8] = (char)((regECX >>  0) & 0xFF);
			sCPU[ 9] = (char)((regECX >>  8) & 0xFF);
			sCPU[10] = (char)((regECX >> 16) & 0xFF);
			sCPU[11] = (char)((regECX >> 24) & 0xFF);
		}
		if( !(regEDX & 0x70000000) )
		{
			sCPU[12] = (char)((regEDX >>  0) & 0xFF);
			sCPU[13] = (char)((regEDX >>  8) & 0xFF);
			sCPU[14] = (char)((regEDX >> 16) & 0xFF);
			sCPU[15] = (char)((regEDX >> 24) & 0xFF);
		}
		if(sCPU[0] < 4)
		{
			for(int i = 1; i < 16; ++i)
			{
				switch(sCPU[i])
				{
				case 0x00:
					//niente
					break;
				case 0x01:
					printf("Instruction TBL: 4K-Byte Pages, 4 way set
associative, 64 entry\n");
					break;
				case 0x02:
					printf("Instruction TBL: 4M-Byte Pages, 4 way set
associative, 4 entry\n");
					break;
				case 0x03:
					printf("Data TBL: 4K-Byte Pages, 4 way set associative,
64 entry\n");
					break;
				case 0x04:
					printf("Data TBL: 4M-Byte Pages, 4 way set associative,
8 entry\n");
					break;
				case 0x06:
					printf("Istruction cache: 8K-Byte, 4 way set
associative, 32 byte line size\n");
					break;
				case 0x07:
					printf("Istruction cache: 16K-Byte, 4 way set
associative, 32 byte line size??\n");
					break;
				case 0x08:
					printf("Istruction cache: 32K-Byte, 4 way set
associative, 32 byte line size\n");
					break;
				case 0x0A:
					printf("Data cache: 8K-Byte, 2 way set associative, 32
byte line size\n");
					break;
				case 0x0B:
					printf("Data cache: 16K-Byte, 2 way set associative, 32
byte line size??\n");
					break;
				case 0x0C:
					printf("Data cache: 32K-Byte, 2 way set associative, 32
byte line size\n");
					break;
				case 0x41:
					printf("Cache L2: 128K-Byte, 4 way set associative, 32
byte line size\n");
					break;
				case 0x42:
					printf("Cache L2: 256K-Byte, 4 way set associative, 32
byte line size\n");
					break;
				case 0x43:
					printf("Cache L2: 512K-Byte, 4 way set associative, 32
byte line size\n");
					break;
				case 0x44:
					printf("Cache L2: 1024K-Byte, 4 way set associative, 32
byte line size\n");
					break;
				default:
					printf("Codice sconosciuto\n");
					break;
				}
			}
		}
		else
		{
			printf("Maledetta Intel, Step 2 fallito perche' era
necessario ripetere %i\n", int(sCPU[0]));
			printf("l'istruzione CPUID per avere risultati corretti!\n");
		}
	}	
	if(step3)
	{
		printf("\nPresente la possibilita' di sapere ulteriori
informazioni\n");
		printf("su questo processore. Al momento della scrittura del
codice\n");
		printf("le informazioni per gestire queste opzioni non erano
note\n");
		printf("al Papero programmatore\n");
	}
 
	printf("\n");
}
void drive(void)
{
	char sDriverLogici[1024];
	char sPath[1024];
	int pos = 0;
	char sRisultato[256];
	char sVolume[64];
	memset(sDriverLogici,0, sizeof(sDriverLogici));
	if(GetLogicalDriveStrings(1024, sDriverLogici))
	{
		UINT tipo;
		DWORD cluster, byte, sector, free;
 		DWORD serialnum, sizeFS, flag;
		bool bEseguiTest;
		double dValore;
		while(true)
		{
			//copio un driver logico
			strcpy(sPath, sDriverLogici + pos);
			//ultima stringa?
			if(0 == strlen(sPath))
			{
				break;
			}
			//lunghezza stringa per il prossimo giro
			//tengo conto dello zero terminale
			pos += strlen(sPath) + 1;
			//tipo di driver
			tipo = GetDriveType(sPath);
			memset(sRisultato,0, sizeof(sRisultato));
			switch(tipo)
			{
			case DRIVE_UNKNOWN:
				strcat(sRisultato, "tipo di drive non determinabile");
				break;
			case DRIVE_NO_ROOT_DIR:
				strcat(sRisultato, "drive senza root directory");
				break;
			case DRIVE_REMOVABLE:
				strcat(sRisultato, "drive rimovibile");
				break;
			case DRIVE_FIXED:
				strcat(sRisultato, "drive fisso");
				break;
			case DRIVE_REMOTE:
				strcat(sRisultato, "drive remoto");
				break;
			case DRIVE_CDROM:
				strcat(sRisultato, "cdrom");
				break;
			case DRIVE_RAMDISK:
				strcat(sRisultato, "ramdisk");
				break;
			}
			printf("Directory %s (%s)\n", sPath, sRisultato);
			if(tipo == DRIVE_REMOVABLE || tipo == DRIVE_REMOTE || tipo ==
DRIVE_CDROM)
			{
				//esiste un media rimovibile in questo drive?
				bEseguiTest = false;
				if(!_getcwd( sRisultato, 256 ))
				{
					if(_chdir(sPath) != -1)
					{
						bEseguiTest = true;
					}
					_chdir(sRisultato);
				}
			}
			else
			{
				bEseguiTest = true;
			}
			if(bEseguiTest)
			{
				if(GetDiskFreeSpace(sPath, &sector, &byte, &free,
&cluster))
				{
	 				printf("Numero totale di cluster: %u\n", cluster);
	 				printf("Settori per cluster: %u\n", sector);
	 				printf("Dimensione di un settore: %u byte\n", byte);
					dValore = double(sector * byte) * double(cluster) /
(1024 * 1024);
	 				printf("Spazio totale: %.0f Mb\n", dValore); 
					dValore = double(sector * byte) * double(free) / (1024
* 1024);
	 				printf("Spazio libero: %.0f Mb (%i%%)\n", dValore,
UINT(free * 100 / cluster));
				}
			}
			if(GetVolumeInformation(sPath, sVolume, 64,
				&serialnum, &sizeFS, &flag, sRisultato, 256))
			{
				printf("Nome del volume: %s\n", sVolume);
				printf("File System: %s\n", sRisultato);
				printf("Dimensione massima per il nome di un file: %u\n",
sizeFS);
				printf("Numero seriale: %X\n", serialnum);
				if(flag & FS_CASE_IS_PRESERVED)
				{
					printf("File system con memoria del case sensitive\n");
				}
				if(flag & FS_CASE_SENSITIVE)
				{
					printf("Nomi file case sensitive\n");
				}
				if(flag & FS_UNICODE_STORED_ON_DISK)
				{
					printf("File system Unicode\n");
				}
				if(flag & FS_PERSISTENT_ACLS)
				{
					printf("File system che accetta le ACLS (diritti di
sicurezza)\n");
				}
				if(flag & FS_FILE_COMPRESSION)
				{
					printf("File system comprimibile\n");
				}
				if(flag & FS_VOL_IS_COMPRESSED)
				{
					printf("Drive compresso");
				}
				if(flag & FILE_SUPPORTS_ENCRYPTION)
				{
					printf("File system criptabile\n");
				}
				if(flag & FS_VOL_IS_COMPRESSED)
				{
					printf("File system con supporto Object ID\n");
				}
				if(flag & FILE_SUPPORTS_REPARSE_POINTS)
				{
					printf("File system con supporto reparse points (non
cosa siano)\n");
				}
				if(flag & FILE_SUPPORTS_SPARSE_FILES)
				{
					printf("File system con file radi (prevalentemente
vuoti)\n");
				}
				if(flag & FILE_VOLUME_QUOTAS)
				{
					printf("File system con supporto per le \"quote\"\n");
				}
			}
			printf("\n");
		}
	}
 
	if(GetTempPath(1024, sPath))
	{
		printf("\nDirectory per i file temporanei = %s\n", sPath);
	}
}
void os (void)
{
	OSVERSIONINFO osvi;
	memset(&osvi, 0, sizeof(osvi));
	osvi.dwOSVersionInfoSize = sizeof(osvi);
	printf("\n");
	if(GetVersionEx (&osvi))
	{
		switch(osvi.dwPlatformId)
		{
		case VER_PLATFORM_WIN32_WINDOWS:
			if(0 == osvi.dwMinorVersion)
			{
				printf("Sistema Operativo: Win95 Build %i %s\n",
osvi.dwBuildNumber, osvi.szCSDVersion);
			}
			else
			{
				printf("Sistema Operativo: Win98 Build %i %s\n",
osvi.dwBuildNumber, osvi.szCSDVersion );
			}
			break;
		case VER_PLATFORM_WIN32_NT:
				printf("Sistema Operativo: NT %i.%i Build %i %s\n",
osvi.dwMajorVersion, osvi.dwMinorVersion, osvi.dwBuildNumber,
osvi.szCSDVersion);
			break;
		default:
			printf("Sistema Operativo sconosciuto Major %i, Minor %i,
Build %i %s\n", osvi.dwMajorVersion, osvi.dwMinorVersion,
osvi.dwBuildNumber, osvi.szCSDVersion);
			break;
		}
	}
}
void memory (void)
{
	MEMORYSTATUS stat;
	const int DIV = 1024 * 1024;
	memset(&stat, 0, sizeof(stat));
	stat.dwLength = sizeof(stat);
	GlobalMemoryStatus(&stat);
  printf ("Percentuale di memoria in uso %ld%%\n\n",
stat.dwMemoryLoad);
  printf ("Memoria fisica totale: %ld\n",   stat.dwTotalPhys/DIV);
  printf ("Memoria fisica libera: %ld\n",   stat.dwAvailPhys/DIV);
  printf ("Memoria paginata totale: %ld\n", stat.dwTotalPageFile/DIV);
  printf ("Memoria paginata libera: %ld\n", stat.dwAvailPageFile/DIV);
  printf ("Memoria virtuale totale: %ld\n", stat.dwTotalVirtual /DIV);
  printf ("Memoria virtuale libera: %ld\n", stat.dwAvailVirtual /DIV);
}
int main(int argc, char* argv[])
{
	//intestazione
	printf("CPUID 0.4.0 - PaperoBench di Davide Quack - Ottobre
2000\n");
	printf("Sito ufficioso:
http://utenti.tripod.it/papero/index.html\n\n
");
 
	//dati sulla frequenza
	rdtsc();
	//dati sul processore
	cpuid();
#ifdef WIN32
	//dati sui drive
	drive();
	//dati sul sistema operativo
	os();
	//dati sulla memoria
	memory();
#endif
	return 0;
}
 
-- 
Tieni per te il Papero giusto se vuoi la mia email
Sito Papero 1 -> 
http://utenti.tripod.it/papero
Sito Papero 2 -> 
http://user.7host.com/papero/

File:					cpuid.cpp
Con quale compilatore ?
--
CyberWalkie - walkietalkie(at)
libero.it

Con quale compilatore ?
VC++
Comunque ho una versione anche per GCC se ricordo bene
