PDA

View Full Version : BENCHMARK CPU in C++: Parere


3nigma666
02-05-2005, 19:36
Salve a tutti,
stamane ho deciso di creare un piccolo benchmark per CPU.
L'idea di fondo è questa:
prendo un algoritmo di Ordinamento,uno abb. snello ,nel mio caso il QuickSort e lo utilizzo per ordinare piu e piu volte vettori generati casualmente di 100 elementi (valore cmq variabile e decidibile a priori)
Il programma calcola la media su n numero di campioni.
In sostanza funziona cosi:

La funzione exec ripete n_volte la creazione di un vettore di 100 elementi random e il suo ordinamento,fino a quando il tmepo di esecuzione non è arrivato a 2 secondi.
La funzione exec viene poi a sua volta ripetuta 100 volte (campioni) per avere un valore medio statisticamente attendibile.

sucessivamente la funzione cpu_id prende dal processore tutti i valori relativi alla sua identita , Family, class,produttore,label ecc e lo comunica a schermo.

Il programma successivamente identifica anke il sistema operativo,in quanto ovviamente differenti sistemi operativi (linux) influsicono sul risultato.

vi posto ora il codice ,e vi prego commentatemelo,specialmente con critiche..fatemi sapere se l'idea ke ho avuto per fare un benchmark su un processore puo essere ritenuta valida,se non valida o ke modifiche apportare... criticate criticate criticate .. ke solo cosi si migliore :D

ovviamente il codice è ancora in versione beta ed è abb. spartano. L'ho compilato con devc++ per ki dovesse avere problemi con visual studio.
grazie a tutti:

#include <cstdlib>
#include <iostream>
#include <stdio.h>
#include "main.h"
#include <time.h>
#include <math.h>
#include <stdlib.h>

/*Programmed By Valerio Bignardi
*Thanks To:
*
*Intel and AMD x86 CPUID display program v 3.3 (1 Jan 2002)
* Copyright 2002 Phil Karn, KA9Q
* May be used under the terms of the GNU Public License (GPL)
*/

#include <stdio.h>

void decode_intel_tlb(int);
void decode_cyrix_tlb(int);
void dointel(int),doamd(int),docyrix(int);
void printregs(int eax,int ebx,int ecx,int edx);
void benchmark();
void savefile(long punt);

#define MAXBRANDS 9
char *Brands[MAXBRANDS] = {
"brand 0",
"Celeron processor",
"Pentium III processor",
"Intel Pentium III Xeon processor",
"brand 4",
"brand 5",
"brand 6",
"brand 7",
"Intel Pentium 4 processor",
};

#define cpuid(in,a,b,c,d)\
asm("cpuid": "=a" (a), "=b" (b), "=c" (c), "=d" (d) : "a" (in));
//-------------------------------------
// Name : Menu()
// Desc : GUI Utente
// Todo : Nulla ;)
//------------------------------------------

int menu(){
int scelta = 0;
std::cout<<std::endl;
std::cout<<"1.Individua il Proprio Processore"<<std::endl;
std::cout<<"2.Run BenchMark"<<std::endl;;
std::cout<<"0.Fine"<<std::endl;
std::cout<<std::endl;
std::cin>>scelta;
return scelta;
}
//-----------------------------
// Name : Percentuale
// Desc : Calcola la percentuale di avanzamento
// ToDo : Implementarla
//----------------------------------------------
double percentuale (int campionatura) {
double unpercento = 0;
unpercento = (double)100/campionatura;
return unpercento;
}


void savefile (float punt){
if ((file = fopen("punteggio.txt","r"))==NULL){
if ((file = fopen("punteggio.txt","a"))==NULL)
exit (1);
else
fprintf(file," .....:::::CPU Speed Beta 0.1 Powered Valerio Bignardi Alias Eni:::::.....\n\n");
#if defined __linux__
fprintf(file,"OS rilevato: linux\n");
#elif defined WIN32
fprintf(file,"OS rilevato: Windows\n");
#endif
run = true; // Impostando a True il valore di run, printregs non comunichera a schermo il valore di string
for(int j=0x80000002;j<=0x80000004;j++){
unsigned long eax,ebx,ecx,edx;
cpuid(j,eax,ebx,ecx,edx);
printregs(eax,ebx,ecx,edx);
}
fprintf(file,"\n");
fprintf(file,"Punteggio: %.0f\n",punt);
fprintf(file,"=================================================\n");
run = false;
}else{
if ((file = fopen("punteggio.txt","a"))==NULL)
exit (1);
#if defined __linux__
fprintf(file,"OS rilevato: linux\n");
#elif defined WIN32
fprintf(file,"OS rilevato: Windows\n");
#endif
run = true;
for(int j=0x80000002;j<=0x80000004;j++){
unsigned long eax,ebx,ecx,edx;
cpuid(j,eax,ebx,ecx,edx);
printregs(eax,ebx,ecx,edx);
}
fprintf(file,"\n");
fprintf(file,"Punteggio: %.0f\n",punt);
fprintf(file,"=================================================\n");
run = false; //reimposto a false il valore di run cosi printregs puo nuovamente stampare a schermo
fclose(file);
}
}//end save
////////////////////////////////////////////////////////////
// Calcolo BenchMark
///////////////////////////////////////////////////////////
//-------------------------------------------------
// Name : Random
// Desc : Genera Numeri Casuali
// ToDo : Nulla
//-------------------------------------------------
double Random()
{
double lo, hi, test;
hi = ceil(seed / Q);
lo = seed - Q * hi;
test = A * lo - R * hi;
if (test < 0.0) {
seed = test + M;
} else {
seed = test;
} /* endif */
return seed / M;
} //end random

//-----------------------------------------
// Name : Creavett
// Desc : Genera i vettori da ordinare
//-----------------------------------------

void creavett(){
for (int i=0; i<max;i++)
vettore[i] =(long)( Random()*500000);
}


//--------------------------------------------------------------------------------
// Name : swap(long& a, long& b)
// Desc : Questa funzione implementa lo scambio dei valori con
// la tecnica inplace, ovverosia senza alcuna variabile di supporto
// Si noti che i parametri sono passati per riferimento, altrimenti
// le modifiche sarebbero effettuate su copie di essi, e lo scambio di valore non ci sarebbe.
// ^= è il simbolo di Xor. Eseguo un Xor per scambiare i valori
// ToDo : Nulla :D
// Vers : 1.0
//----------------------------------------------------------------------------------------

void swap (long& a, long& b) {
a ^= b ^= a ^= b; //Metodo inplace per scambiare i valori di a e b
};

////////////////////////////////////////////////////////////////////////////////
// QUICKSORT
////////////////////////////////////////////////////////////////////////////////

//-----------------------------------------------------------------------
// Name : Partition
// Desc : Prende come parametri puntatore ad un vettore, indice sinistro ,indice destro
// Inizia a scorrerre il vettore partendo da fuori il vettore
// e inizia un loop ke continua fino a quando l'indice sx è minore dell'indice dx
// Dentro al loop viene fatto scorrere il vettore e ogni singolo elemento del vettore
// viene confrontato con il pivot e se maggiore viene messo a dx se inferiore viene
// posizionato a sx tramite la funzione swap
// ToDo : Nulla
// Vers : 1.0
// Bugs : N.P.
//-----------------------------------------------------------------------------------------

int Partition (long* vett,int left,int right){
pivot = vett[left];//a pivot assegno il primo elemento
i = left - 1 ; //inizio da fuori il vettore
j = right + 1; //inizio da fuori il vettore
//fino a quando l indice inferiore non supera l indice superiore continua a cercare gli elementi
while (i < j){
do{j--;} //decrementa di una posizione l'indice superiore
while (vett[j]>pivot); //continua a decrementare fino a quando l elemento trovato nn è maggiore del pivot
do{
i++;
}while (vett[i]<pivot);//continua a decrementare fino a quando l elemento trovato nn è minore del pivot
if (i<j)
swap(vett[i],vett[j]);//inverti i due valori
else
return j;// se i ha superato j ritorno il nuovo pivot a Qsort
}//end while
}//end partition

//-------------------------------------------------------------
// Name : QuickSort
// Desc : Assegna un valore a al pivot q.la funzione richiama se stessa
// ricorsivamente passandosi prima l'albero di dx e poi quello di sx
// ToDO : Nulla :D
// Vers : 1.0
// Bugs : N.P
//-----------------------------------------------------------

void QuickSort (long* vett,int left,int right){
if (left < right){
q = Partition (vett,left,right); //Assegnazione pivot
QuickSort(vett,left,q);//albero di sinistra
QuickSort(vett,q+1,right);//albero di destra
}//end if

}//end quicksort



long int Tara (){
t2 = 0;
t3 = 0;
t2 = clock();
creavett();
t3 = clock();
return (t3 - t2);
}
//----------------------------------------------
// Name : exec ()
// Desc : Richiama la funzione quicksort e Calcola il tempo
// impiegato e il numero di volte in cui è stato ordinato il vettore
// Nel Tempi minimo (Tmin) Richiesto
// ToDo : Nothing ;D
//-----------------------------------------------------------

int exec() {
int t = 0;
t0 = clock();
do{
creavett();//creo un nuovo vettore da ordinare
QuickSort(vettore,0,(max - 1)); // richiamo QuickSort
t++; //incremento il contatore
t1 = clock();
tot = (t1 - t0) - Tara();
tot_effettivo = tot;
tot_sec = (double)tot_effettivo/CLOCKS_PER_SEC;

}while (tot_sec < Tmin );
//std::cout<<"Il punteggio effettuato e': "<<t<<std::endl;
return t;
}//End exec


//-----------------------------------
// Name : BenchMark
// Desc : Esegue un numero di volte pari a campioni la funzione exec
// Questo per avere un VALORE MEDIO del punteggio ottenuto
// ToDo : Nulla
//------------------------------------------------------------
void BenchMark (){
long punteggio_parz = 0;
perc = 0;
//pulisco lo schermo
#if defined __linux__
system("clear");
std::cout<<"OS: Linux"<<std::endl;
#elif defined WIN32
system("cls");
std::cout<<"OS: Windows"<<std::endl;
#endif
for(int j=0x80000002;j<=0x80000004;j++){
unsigned long eax,ebx,ecx,edx;
cpuid(j,eax,ebx,ecx,edx);
printregs(eax,ebx,ecx,edx);
}
std::cout<<std::endl;
std::cout<<"Progresso: "<<perc<<" %"<<std::endl; //inizializzo a schermo il progresso
for (int j=0;j<campioni;j++){
punteggio_parz += exec();// eseguo l ordinamento
//faccio un refresh dello della percentuale
#if defined __linux__
system("clear");
std::cout<<"OS: Linux"<<std::endl;
#elif defined WIN32
system("cls");
std::cout<<"OS: Windows"<<std::endl;
#endif
for(int j=0x80000002;j<=0x80000004;j++){
unsigned long eax,ebx,ecx,edx;
cpuid(j,eax,ebx,ecx,edx);
printregs(eax,ebx,ecx,edx);
}
perc += percentuale(campioni);
std::cout<<std::endl;
std::cout<<"Progresso: "<<perc<<" %"<<std::endl;// aggiorno percentuale attuale
}//end for
punteggio = punteggio_parz / campioni; //calcolo il punteggio medio ottenuto
std::cout<<"il punteggio ottenuto e': "<< punteggio <<std::endl; //comunico a schermo il risultato
savefile(punteggio);
}

//-----------------------------------
// Name : cpu_id
// Desc : Identifica il processore
//--------------------------------------

void cpu_id(){

/* Insert code here to test if CPUID instruction is available */

/* Dump all the CPUID results in raw hex */
cpuid(0,maxi,unused,unused,unused);
maxi &= 0xffff; /* The high-order word is non-zero on some Cyrix CPUs */
//Stampa contenuto eax ebx ecx edx
/* printf(" eax in eax ebx ecx edx\n");
for(i=0;i<=maxi;i++){
unsigned long eax,ebx,ecx,edx;

cpuid(i,eax,ebx,ecx,edx);
printf("%08x %08lx %08lx %08lx %08lx\n",i,eax,ebx,ecx,edx);
}*/
cpuid(0x80000000,maxei,unused,unused,unused);
/* for(li=0x80000000;li<=maxei;li++){
unsigned long eax,ebx,ecx,edx;

cpuid(li,eax,ebx,ecx,edx);
printf("%08lx %08lx %08lx %08lx %08lx\n",li,eax,ebx,ecx,edx);
}*/
printf("\n");

/* Vendor ID and max CPUID level supported */
cpuid(0,unused,ebx,ecx,edx);
printf("Vendor ID: \"");
for(i=0;i<4;i++)
putchar(ebx >> (8*i));
for(i=0;i<4;i++)
putchar(edx >> (8*i));
for(i=0;i<4;i++)
putchar(ecx >> (8*i));
printf("\"; CPUID level %ld\n\n",maxi);


switch(ebx){
case 0x756e6547: /* Intel */
dointel(maxi);
break;
case 0x68747541: /* AMD */
doamd(maxi);
break;
case 0x69727943: /* Cyrix */
docyrix(maxi);
break;
default:
printf("Unknown vendor\n");
break;
}
}//End cpu_id
//-------------------------------
// Name : Main
// Desc : Il main richiama le funzioni necessarie per il BenchMark e per l'identificazione del
// Processore
// ToDo : Salvare su file
//--------------------------------------------------------------------------

int main(){
seed = 123456789;
std::cout<<"\t\t\t Speed Cpu Test beta 0.1";
std::cout<<std::endl;
std::cout<<"\t\t Programma Di Valerio Bignardi"<<std::endl;
std::cout<<std::endl;
#if defined __linux__
std::cout<<"\t\t\t OS Rilevato: linux"<<std::endl;
#elif defined WIN32
std::cout<<"\t\t\t OS Rilevato: Win32"<<std::endl;
#endif

int scelta = 0;

do{
scelta = menu();
switch (scelta){
case 1: cpu_id() ;break;
case 2: BenchMark();break;
case 0: exit (0);break;

}//End switch
}while (scelta != 0);
}// end main



//////////////////////////////////////////////////////////
// Identificazione CPU e Features
//////////////////////////////////////////////////////////
char *Intel_feature_flags[] = {
"FPU Floating Point Unit",
"VME Virtual 8086 Mode Enhancements",
"DE Debugging Extensions",
"PSE Page Size Extensions",
"TSC Time Stamp Counter",
"MSR Model Specific Registers",
"PAE Physical Address Extension",
"MCE Machine Check Exception",
"CX8 COMPXCHG8B Instruction",
"APIC On-chip Advanced Programmable Interrupt Controller present and enabled",
"10 Reserved",
"SEP Fast System Call",
"MTRR Memory Type Range Registers",
"PGE PTE Global Flag",
"MCA Machine Check Architecture",
"CMOV Conditional Move and Compare Instructions",
"FGPAT Page Attribute Table",
"PSE-36 36-bit Page Size Extension",
"PN Processor Serial Number present and enabled",
"CLFSH CFLUSH instruction",
"20 reserved",
"DS Debug store",
"ACPI Thermal Monitor and Clock Ctrl",
"MMX MMX instruction set",
"FXSR Fast FP/MMX Streaming SIMD Extensions save/restore",
"SSE Streaming SIMD Extensions instruction set",
"SSE2 SSE2 extensions",
"SS Self Snoop",
"HT Hyper Threading",
"TM Thermal monitor",
"30 reserved",
"31 reserved",
};

/* Intel-specific information */
void dointel(int maxi){
printf("Intel-specific functions:\n");

if(maxi >= 1){
/* Family/model/type etc */
int clf,apic_id,feature_flags;
int extended_model = -1,extended_family = -1;
unsigned long eax,ebx,edx,unused;
int stepping,model,family,type,reserved,brand,siblings;
int i;

cpuid(1,eax,ebx,unused,edx);
printf("Version %08lx:\n",eax);
stepping = eax & 0xf;
model = (eax >> 4) & 0xf;
family = (eax >> 8) & 0xf;
type = (eax >> 12) & 0x3;
reserved = eax >> 14;
clf = (ebx >> 8) & 0xff;
apic_id = (ebx >> 24) & 0xff;
siblings = (ebx >> 16) & 0xff;
feature_flags = edx;

printf("Type %d - ",type);
switch(type){
case 0:
printf("Original OEM");
break;
case 1:
printf("Overdrive");
break;
case 2:
printf("Dual-capable");
break;
case 3:
printf("Reserved");
break;
}
printf("\n");

printf("Family %d - ",family);
switch(family){
case 3:
printf("i386");
break;
case 4:
printf("i486");
break;
case 5:
printf("Pentium");
break;
case 6:
printf("Pentium Pro");
break;
case 15:
printf("Pentium 4");
}
printf("\n");
if(family == 15){
extended_family = (eax >> 20) & 0xff;
printf("Extended family %d\n",extended_family);
}
printf("Model %d - ",model);
switch(family){
case 3:
break;
case 4:
switch(model){
case 0:
case 1:
printf("DX");
break;
case 2:
printf("SX");
break;
case 3:
printf("487/DX2");
break;
case 4:
printf("SL");
break;
case 5:
printf("SX2");
break;
case 7:
printf("write-back enhanced DX2");
break;
case 8:
printf("DX4");
break;
}
break;
case 5:
switch(model){
case 1:
printf("60/66");
break;
case 2:
printf("75-200");
break;
case 3:
printf("for 486 system");
break;
case 4:
printf("MMX");
break;
}
break;
case 6:
switch(model){
case 1:
printf("Pentium Pro");
break;
case 3:
printf("Pentium II Model 3");
break;
case 5:
printf("Pentium II Model 5/Xeon/Celeron");
break;
case 6:
printf("Celeron");
break;
case 7:
printf("Pentium III/Pentium III Xeon - external L2 cache");
break;
case 8:
printf("Pentium III/Pentium III Xeon - internal L2 cache");
break;
}
break;
case 15:
break;
}
printf("\n");
if(model == 15){
extended_model = (eax >> 16) & 0xf;
printf("Extended model %d\n",extended_model);
}
printf("Stepping %d\n",stepping);

printf("Reserved %d\n\n",reserved);

brand = ebx & 0xff;
if(brand > 0){
printf("Brand index: %d [",brand);
if(brand < MAXBRANDS){
printf("%s]\n",Brands[brand]);
} else {
printf("not in table]\n");
}
}
cpuid(0x80000000,eax,ebx,unused,edx);
if(eax & 0x80000000){
/* Extended feature/signature bits supported */
int maxe = eax;
if(maxe >= 0x80000004){
int i;

printf("Extended brand string: \"");
for(i=0x80000002;i<=0x80000004;i++){
unsigned long eax,ebx,ecx,edx;

cpuid(i,eax,ebx,ecx,edx);
printregs(eax,ebx,ecx,edx);
}
printf("\"\n");
}
}
if(clf)
printf("CLFLUSH instruction cache line size: %d\n",clf);

if(apic_id)
printf("Initial APIC ID: %d\n",apic_id);

if(feature_flags & (1<<28)){
printf("Hyper threading siblings: %d\n",siblings);
}

printf("\nFeature flags %08x:\n",feature_flags);
for(i=0;i<32;i++){
if(feature_flags & (1<<i)){
printf("%s\n",Intel_feature_flags[i]);
}
}
printf("\n");
}
if(maxi >= 2){
/* Decode TLB and cache info */
int ntlb,i;

ntlb = 255;
printf("TLB and cache info:\n");
for(i=0;i<ntlb;i++){
unsigned long eax,ebx,ecx,edx;

cpuid(2,eax,ebx,ecx,edx);
ntlb = eax & 0xff;
decode_intel_tlb(eax >> 8);
decode_intel_tlb(eax >> 16);
decode_intel_tlb(eax >> 24);

if((ebx & 0x80000000) == 0){
decode_intel_tlb(ebx);
decode_intel_tlb(ebx >> 8);
decode_intel_tlb(ebx >> 16);
decode_intel_tlb(ebx >> 24);
}
if((ecx & 0x80000000) == 0){
decode_intel_tlb(ecx);
decode_intel_tlb(ecx >> 8);
decode_intel_tlb(ecx >> 16);
decode_intel_tlb(ecx >> 24);
}
if((edx & 0x80000000) == 0){
decode_intel_tlb(edx);
decode_intel_tlb(edx >> 8);
decode_intel_tlb(edx >> 16);
decode_intel_tlb(edx >> 24);
}
}
}
if(maxi >= 3){
/* Pentium III CPU serial number */
unsigned long signature,unused,ecx,edx;

cpuid(1,signature,unused,unused,unused);
cpuid(3,unused,unused,ecx,edx);
printf("Processor serial: ");
printf("%04lX",signature >> 16);
printf("-%04lX",signature & 0xffff);
printf("-%04lX",edx >> 16);
printf("-%04lX",edx & 0xffff);
printf("-%04lX",ecx >> 16);
printf("-%04lX\n",ecx & 0xffff);
}
}
void printregs(int eax,int ebx,int ecx,int edx){
int j;

string[16] = '\0';
for(j=0;j<4;j++){
string[j] = eax >> (8*j);
string[j+4] = ebx >> (8*j);
string[j+8] = ecx >> (8*j);
string[j+12] = edx >> (8*j);
}
if (run == false)
printf("%s",string);
else
fprintf(file,"%s",string);
}


/* Decode Intel TLB and cache info descriptors */
void decode_intel_tlb(int x){
x &= 0xff;
if(x != 0)
printf("%02x: ",x);
switch(x){
case 0:
break;
case 0x1:
printf("Instruction TLB: 4KB pages, 4-way set assoc, 32 entries\n");
break;
case 0x2:
printf("Instruction TLB: 4MB pages, 4-way set assoc, 2 entries\n");
break;
case 0x3:
printf("Data TLB: 4KB pages, 4-way set assoc, 64 entries\n");
break;
case 0x4:
printf("Data TLB: 4MB pages, 4-way set assoc, 8 entries\n");
break;
case 0x6:
printf("1st-level instruction cache: 8KB, 4-way set assoc, 32 byte line size\n");
break;
case 0x8:
printf("1st-level instruction cache: 16KB, 4-way set assoc, 32 byte line size\n");
break;
case 0xa:
printf("1st-level data cache: 8KB, 2-way set assoc, 32 byte line size\n");
break;
case 0xc:
printf("1st-level data cache: 16KB, 4-way set assoc, 32 byte line size\n");
break;
case 0x40:
printf("No 2nd-level cache, or if 2nd-level cache exists, no 3rd-level cache\n");
break;
case 0x41:
printf("2nd-level cache: 128KB, 4-way set assoc, 32 byte line size\n");
break;
case 0x42:
printf("2nd-level cache: 256KB, 4-way set assoc, 32 byte line size\n");
break;
case 0x43:
printf("2nd-level cache: 512KB, 4-way set assoc, 32 byte line size\n");
break;
case 0x44:
printf("2nd-level cache: 1MB, 4-way set assoc, 32 byte line size\n");
break;
case 0x45:
printf("2nd-level cache: 2MB, 4-way set assoc, 32 byte line size\n");
break;
case 0x50:
printf("Instruction TLB: 4KB and 2MB or 4MB pages, 64 entries\n");
break;
case 0x51:
printf("Instruction TLB: 4KB and 2MB or 4MB pages, 128 entries\n");
break;
case 0x52:
printf("Instruction TLB: 4KB and 2MB or 4MB pages, 256 entries\n");
break;
case 0x5b:
printf("Data TLB: 4KB and 4MB pages, 64 entries\n");
break;
case 0x5c:
printf("Data TLB: 4KB and 4MB pages, 128 entries\n");
break;
case 0x5d:
printf("Data TLB: 4KB and 4MB pages, 256 entries\n");
break;
case 0x66:
printf("1st-level data cache: 8KB, 4-way set assoc, 64 byte line size\n");
break;
case 0x67:
printf("1st-level data cache: 16KB, 4-way set assoc, 64 byte line size\n");
break;
case 0x68:
printf("1st-level data cache: 32KB, 4-way set assoc, 64 byte line size\n");
break;
case 0x70:
printf("Trace cache: 12K-micro-op, 4-way set assoc\n");
break;
case 0x71:
printf("Trace cache: 16K-micro-op, 4-way set assoc\n");
break;
case 0x72:
printf("Trace cache: 32K-micro-op, 4-way set assoc\n");
break;
case 0x79:
printf("2nd-level cache: 128KB, 8-way set assoc, sectored, 64 byte line size\n");
break;
case 0x7a:
printf("2nd-level cache: 256KB, 8-way set assoc, sectored, 64 byte line size\n");
break;
case 0x7b:
printf("2nd-level cache: 512KB, 8-way set assoc, sectored, 64 byte line size\n");
break;
case 0x7c:
printf("2nd-level cache: 1MB, 8-way set assoc, sectored, 64 byte line size\n");
break;
case 0x82:
printf("2nd-level cache: 256KB, 8-way set assoc, 32 byte line size\n");
break;
case 0x83:
printf("2nd-level cache: 512KB, 8-way set assoc 32 byte line size\n");
break;
case 0x84:
printf("2nd-level cache: 1MB, 8-way set assoc, 32 byte line size\n");
break;
case 0x85:
printf("2nd-level cache: 2MB, 8-way set assoc, 32 byte line size\n");
break;
default:
printf("unknown TLB/cache descriptor\n");
break;
}
}
char *AMD_feature_flags[] = {
"Floating Point Unit",
"Virtual Mode Extensions",
"Debugging Extensions",
"Page Size Extensions",
"Time Stamp Counter (with RDTSC and CR4 disable bit)",
"Model Specific Registers with RDMSR & WRMSR",
"PAE - Page Address Extensions",
"Machine Check Exception",
"COMPXCHG8B Instruction",
"APIC",
"10 - Reserved",
"SYSCALL/SYSRET or SYSENTER/SYSEXIT instructions",
"MTRR - Memory Type Range Registers",
"Global paging extension",
"Machine Check Architecture",
"Conditional Move Instruction",
"PAT - Page Attribute Table",
"PSE-36 - Page Size Extensions",
"18 - reserved",
"19 - reserved",
"20 - reserved",
"21 - reserved",
"AMD MMX Instruction Extensions",
"MMX instructions",
"FXSAVE/FXRSTOR",
"25 - reserved",
"26 - reserved",
"27 - reserved",
"28 - reserved",
"29 - reserved",
"3DNow! Instruction Extensions",
"3DNow instructions",
};

char *Assoc[] = {
"L2 off",
"Direct mapped",
"2-way",
"reserved",
"4-way",
"reserved",
"8-way",
"reserved",
"16-way",
"reserved",
"reserved",
"reserved",
"reserved",
"reserved",
"reserved",
"full",
};



/* AMD-specific information */
void doamd(int maxi){
unsigned long maxei,unused;
int family = 0;

printf("AMD-specific functions\n");

/* Do standard stuff */
if(maxi >= 1){
unsigned long eax,ebx,edx,unused;
int stepping,model,reserved;

cpuid(1,eax,ebx,unused,edx);
stepping = eax & 0xf;
model = (eax >> 4) & 0xf;
family = (eax >> 8) & 0xf;
reserved = eax >> 12;

printf("Version %08lx:\n",eax);
// fprintf(file,"Version %08lx:\n",eax);
printf("Family: %d Model: %d [",family,model);
switch(family){
case 4:
printf("486 model %d",model);
break;
case 5:
switch(model){
case 0:
case 1:
case 2:
case 3:
case 6:
case 7:
printf("K6 Model %d",model);
break;
case 8:
printf("K6-2 Model 8");
break;
case 9:
printf("K6-III Model 9");
break;
default:
printf("K5/K6 model %d",model);
break;
}
break;
case 6:
switch(model){
case 1:
case 2:
case 4:
printf("Athlon model %d",model);
break;
case 3:
printf("Duron model 3");
break;
case 6:
printf("Athlon MP/Mobile Athlon model 6");
break;
case 7:
printf("Mobile Duron Model 7");
break;
default:
printf("Duron/Athlon model %d",model);
break;
}

break;
}
printf("]\n\n");
{
int i;

printf("Standard feature flags %08lx:\n",edx);
for(i=0;i<32;i++){
if(family == 5 && model == 0){
if(i == 9)
printf("Global Paging Extensions\n");
else if(i == 13)
printf("13 - reserved\n");
} else {
if(edx & (1<<i)){
printf("%s\n",AMD_feature_flags[i]);
}
}
}
}
}
/* Check for presence of extended info */
cpuid(0x80000000,maxei,unused,unused,unused);
if(maxei == 0)
return;

if(maxei >= 0x80000001){
unsigned long eax,ebx,ecx,edx;
int stepping,model,generation,reserved;
int i;

cpuid(0x80000001,eax,ebx,ecx,edx);
stepping = eax & 0xf;
model = (eax >> 4) & 0xf;
generation = (eax >> 8) & 0xf;
reserved = eax >> 12;

printf("Generation: %d Model: %d\n",generation,model);
printf("Extended feature flags %08lx:\n",edx);
for(i=0;i<32;i++){
if(family == 5 && model == 0 && i == 9){
printf("Global Paging Extensions\n");
} else {
if(edx & (1<<i)){
printf("%s\n",AMD_feature_flags[i]);
}
}
}
}
printf("\n");
if(maxei >= 0x80000002){
/* Processor identification string */
int j;
printf("Processor name string: ");
for(j=0x80000002;j<=0x80000004;j++){
unsigned long eax,ebx,ecx,edx;

cpuid(j,eax,ebx,ecx,edx);
printregs(eax,ebx,ecx,edx);
}
printf("\n");
}
if(maxei >= 0x80000005){
/* TLB and cache info */
unsigned long eax,ebx,ecx,edx;

cpuid(0x80000005,eax,ebx,ecx,edx);
printf("L1 Cache Information:\n");
if(family >= 6){
printf("2/4-MB Pages:\n");
printf(" Data TLB: associativity %ld-way #entries %ld\n",
(eax >> 24) & 0xff,(eax >> 16) & 0xff);
printf(" Instruction TLB: associativity %ld-way #entries %ld\n",
(eax >> 8) & 0xff,eax & 0xff);
}
printf("4-KB Pages:\n");
printf(" Data TLB: associativity %ld-way #entries %ld\n",
(ebx >> 24) & 0xff,(ebx >> 16) & 0xff);
printf(" Instruction TLB: associativity %ld-way #entries %ld\n",
(ebx >> 8) & 0xff,ebx & 0xff);

printf("L1 Data cache:\n");
printf(" size %ld KB associativity %lx-way lines per tag %ld line size %ld\n",
ecx >> 24,(ecx>>16) & 0xff,(ecx >> 8)&0xff,ecx&0xff);

printf("L1 Instruction cache:\n");
printf(" size %ld KB associativity %lx-way lines per tag %ld line size %ld\n",
edx >> 24,(edx>>16) & 0xff,(edx >> 8)&0xff,edx&0xff);
printf("\n");
}

/* check K6-III (and later?) on-chip L2 cache size */
if (maxei >= 0x80000006) {
unsigned long eax,ebx,ecx,unused;
int assoc;

cpuid(0x80000006,eax,ebx,ecx,unused);
printf("L2 Cache Information:\n");
if(family >= 6){
printf("2/4-MB Pages:\n");
assoc = (eax >> 24) & 0xff;
if(assoc == 6)
assoc = 8;
printf(" Data TLB: associativity %s #entries %ld\n",
Assoc[(eax >> 24) & 0xf],(eax >> 16) & 0xff);
assoc = (eax >> 16) & 0xff;
printf(" Instruction TLB: associativity %s #entries %ld\n",
Assoc[(eax >> 8) & 0xf],eax & 0xff);

printf("4-KB Pages:\n");
printf(" Data TLB: associativity %s #entries %ld\n",
Assoc[(ebx >> 24) & 0xf],(ebx >> 16) & 0xff);
printf(" Instruction TLB: associativity %s #entries %ld\n",
Assoc[(ebx >> 8) & 0xf],ebx & 0xff);
}
printf(" size %ld KB associativity %s lines per tag %ld line size %ld\n",
ecx >> 24,Assoc[(ecx>>16) & 0xf],(ecx >> 8)&0xff,ecx&0xff);

printf("\n");
}
/* Check power management feature flags */
if(maxei >= 0x80000007){
unsigned long unused,edx;

printf("Advanced Power Management Feature Flags\n");
cpuid(0x80000007,unused,unused,unused,edx);
if(edx & 1)
printf("Has temperature sensing diode\n");
if(edx & 2)
printf("Supports Frequency ID control\n");
if(edx & 4)
printf("Supports Voltage ID control\n");
}
/* Check phys address & linear address size */
if(maxei >= 0x80000008){
unsigned long unused,eax;

cpuid(0x80000008,eax,unused,unused,unused);
printf("Maximum linear address: %ld; maximum phys address %ld\n",
(eax>>8) & 0xff,eax&0xff);
}
}

char *Cyrix_standard_feature_flags_5[] = {
"FPU Floating Point Unit",
"V86 Virtual Mode Extensions",
"Debug Extension",
"4MB Page Size",
"Time Stamp Counter",
"RDMSR/WRMSR (Model Specific Registers)",
"PAE",
"Machine Check Exception",
"COMPXCHG8B Instruction",
"APIC - On-chip Advanced Programmable Interrupt Controller present and enabled",
"10 - Reserved",
"11 - Reserved",
"MTRR Memory Type Range Registers",
"13 - reserved",
"Machine Check",
"CMOV Conditional Move Instruction",
"16 - reserved",
"17 - reserved",
"18 - reserved",
"19 - reserved",
"20 - reserved",
"21 - reserved",
"22 - reserved",
"MMX instructions",
"24 - reserved",
"25 - reserved",
"26 - reserved",
"27 - reserved",
"28 - reserved",
"29 - reserved",
"30 - reserved",
};

char *Cyrix_standard_feature_flags_not5[] = {
"FPU Floating Point Unit",
"V86 Virtual Mode Extensions",
"Debug Extension",
"4MB Page Size",
"Time Stamp Counter",
"RDMSR/WRMSR (Model Specific Registers)",
"PAE",
"Machine Check Exception",
"COMPXCHG8B Instruction",
"APIC - On-chip Advanced Programmable Interrupt Controller present and enabled",
"10 - Reserved",
"11 - Reserved",
"MTRR Memory Type Range Registers",
"Global Paging Extension",
"Machine Check",
"CMOV Conditional Move Instruction",
"16 - reserved",
"17 - reserved",
"18 - reserved",
"19 - reserved",
"20 - reserved",
"21 - reserved",
"22 - reserved",
"MMX instructions",
"24 - reserved",
"25 - reserved",
"26 - reserved",
"27 - reserved",
"28 - reserved",
"29 - reserved",
"30 - reserved",
};


char *Cyrix_extended_feature_flags[] = {
"FPU Floating Point Unit",
"V86 Virtual Mode Extensions",
"Debug Extension",
"Page Size Extensions",
"Time Stamp Counter",
"Cyrix MSR",
"PAE",
"MC Exception",
"COMPXCHG8B",
"APIC on chip",
"SYSCALL/SYSRET",
"11 - reserved",
"MTRR",
"Global bit",
"Machine Check",
"CMOV",
"FPU CMOV",
"17 - reserved",
"18 - reserved",
"19 - reserved",
"20 - reserved",
"21 - reserved",
"22 - reserved",
"MMX",
"Extended MMX",
"25 - reserved",
"26 - reserved",
"27 - reserved",
"28 - reserved",
"29 - reserved",
"30 - reserved",
"3DNow instructions",
};

/* Cyrix-specific information */
void docyrix(int maxi){
unsigned long maxei,unused;
int i;

printf("Cyrix-specific functions\n");
cpuid(0x80000000,maxei,unused,unused,unused);
/* Dump extended info, if any, in raw hex */
for(i=0x80000000;i<=maxei;i++){
unsigned long eax,ebx,ecx,edx;

cpuid(i,eax,ebx,ecx,edx);
printf("eax in: 0x%x, eax = %08lx ebx = %08lx ecx = %08lx edx = %08lx\n",i,eax,ebx,ecx,edx);
}

/* Do standard stuff */
if(maxi >= 1){
unsigned long eax,unused,edx;
int stepping,model,family,reserved;

cpuid(1,eax,unused,unused,edx);
stepping = eax & 0xf;
model = (eax >> 4) & 0xf;
family = (eax >> 8) & 0xf;
reserved = eax >> 12;

printf("Family: %d Model: %d [",family,model);
switch(family){
case 4:
switch(model){
case 4:
printf("MediaGX");
break;
}
break;
case 5:
switch(model){
case 2:
printf("6x86");
break;
case 4:
printf("BXm");
break;
}
break;
case 6:
switch(model){
case 0:
printf("6x86/MX");
break;
}
break;
}
printf("]\n\n");
if(family == 5 && model == 0){
int i;

for(i=0;i<32;i++){
if(edx & (1<<i)){
printf("%s\n",Cyrix_standard_feature_flags_5[i]);
}
}
} else {
int i;

for(i=0;i<32;i++){
if(edx & (1<<i)){
printf("%s\n",Cyrix_standard_feature_flags_not5[i]);
}
}
}
}
if(maxi >= 2){
/* TLB and L1 Cache info */
int ntlb = 255;
int i;

for(i=0;i<ntlb;i++){
unsigned long eax,edx,unused;

cpuid(2,eax,unused,unused,edx);
ntlb = eax & 0xff;
decode_cyrix_tlb(eax >> 8);
decode_cyrix_tlb(eax >> 16);
decode_cyrix_tlb(eax >> 24);

/* ebx and ecx are reserved */

if((edx & 0x80000000) == 0){
decode_cyrix_tlb(edx);
decode_cyrix_tlb(edx >> 8);
decode_cyrix_tlb(edx >> 16);
decode_cyrix_tlb(edx >> 24);
}
}
}

/* Check for presence of extended info */
if(maxei < 0x80000000)
return;

printf("\nExtended info:\n");
if(maxei >= 0x80000001){
unsigned long eax,ebx,ecx,edx;
int stepping,model,family,reserved,i;

cpuid(0x80000001,eax,ebx,ecx,edx);
stepping = eax & 0xf;
model = (eax >> 4) & 0xf;
family = (eax >> 8) & 0xf;
reserved = eax >> 12;
printf("Family: %d Model: %d [",family,model);
switch(family){
case 4:
printf("MediaGX");
break;
case 5:
printf("6x86/GXm");
break;
case 6:
printf("6x86/MX");
}
printf("]\n\n");

printf("Extended feature flags:\n");
for(i=0;i<32;i++){
if(edx & (1<<i)){
printf("%s\n",Cyrix_extended_feature_flags[i]);
}
}
}
printf("\n");
if(maxei >= 0x80000002){
/* Processor identification string */
char namestring[49],*cp;
int j;
cp = namestring;
printf("Processor name string: ");
for(j=0x80000002;j<=0x80000004;j++){
unsigned long eax,ebx,ecx,edx;

cpuid(j,eax,ebx,ecx,edx);
printregs(eax,ebx,ecx,edx);
}
}
if(maxei >= 0x80000005){
/* TLB and L1 Cache info */
int ntlb = 255;
int i;

for(i=0;i<ntlb;i++){
unsigned long eax,ebx,ecx,unused;

cpuid(0x80000005,eax,ebx,ecx,unused);
ntlb = eax & 0xff;
decode_cyrix_tlb(ebx >> 8);
decode_cyrix_tlb(ebx >> 16);
decode_cyrix_tlb(ebx >> 24);

/* eax and edx are reserved */

if((ecx & 0x80000000) == 0){
decode_cyrix_tlb(ecx);
decode_cyrix_tlb(ecx >> 8);
decode_cyrix_tlb(ecx >> 16);
decode_cyrix_tlb(ecx >> 24);
}
}
}
}


/* Decode Cyrix TLB and cache info descriptors */
void decode_cyrix_tlb(int x){
switch(x & 0xff){
case 0:
break;
case 0x70:
printf("TLB: 32 entries 4-way associative 4KB pages\n");
break;
case 0x80:
printf("L1 Cache: 16KB 4-way associative 16 bytes/line\n");
break;
}

}

DanieleC88
02-05-2005, 20:04
C'ho dato solo un'occhiata rapida, non posso dare giudizi, ma ti posso dire che non serve distinguere Linux e Windows soltanto con un directive del compilatore. Cioè, si tratta di un progetto che non usa niente di dipendente dal sistema operativo, basterebbe compilarlo (sotto Windows, ad esempio) passando al compilatore l'opzione per predefinire "__linux__", e il programma riporterà il sistema operativo errato.

3nigma666
02-05-2005, 20:10
ok allora intendi dire ke fare tutte le distinzioni tra linux e win sono essenzialmente inutili... ok e fin qui ok poi se hai tempo e voglia,se riesci a dare una occhiata all idea di fondo del benchmark,cioè il modo con il quale calcolo e misuro diociamo la velocita di calcolo,in quanto il risultato in output dal programma nn è altro ke il numero di ordinamenti ke il programma riesce a fare in un tempo stabilito di 2 secondi.
intanto ti dico grazie MILLE per l interessamento :D

3nigma666
02-05-2005, 22:18
Ho ritoccato il codice ,non è piu il primo ke ho postato ma bensi questo ke posto ora.E' composto da 2 file : main.h e main.cpp

main.h:

// Dichairo tutte le variabili necessarie

#define LINUX
#define A 16087
#define M 2147483647
#define Q 127773
#define R 2836

FILE * file;
bool run = false; //false
double perc = 0;
int count = 0;
int const max = 100;
double Tmin = 2;
long vettore [max];
double seed ;
int const campioni = 100;
long int t0 = 0; //Istante di tempo t0
long int t1 = 0;
long int t2 = 0;
long int t3 = 0;
int pivot = 0;
int j = 0; // vriabile richiamata all'interno di Heapify
int q = 0;
int i = 0;
long tempor[max];
long int tot = 0;
long int tot_effettivo = 0;
double tot_sec = 0;
long int tara = 0;
float punteggio = 0;
char string[17];
unsigned long li,maxi,maxei,ebx,ecx,edx,unused;


MAIN.CPP
#include <cstdlib>
#include <iostream>
#include <stdio.h>
#include "main.h"
#include <time.h>
#include <math.h>
#include <stdlib.h>

/*Created By Valerio Bignardi CPUSPEED version alpha 0.9
* Intel and AMD x86 CPUID display program v 3.3 (1 Jan 2002)
* Copyright 2002 Phil Karn, KA9Q
*
* May be used under the terms of the GNU Public License (GPL)
*
*/

#include <stdio.h>

void decode_intel_tlb(int);
void decode_cyrix_tlb(int);
void dointel(int),doamd(int),docyrix(int);
void printregs(int eax,int ebx,int ecx,int edx);
void benchmark();
void savefile(long punt);

#define MAXBRANDS 9
char *Brands[MAXBRANDS] = {
"brand 0",
"Celeron processor",
"Pentium III processor",
"Intel Pentium III Xeon processor",
"brand 4",
"brand 5",
"brand 6",
"brand 7",
"Intel Pentium 4 processor",
};

#define cpuid(in,a,b,c,d)\
asm("cpuid": "=a" (a), "=b" (b), "=c" (c), "=d" (d) : "a" (in));
//-------------------------------------
// Name : Menu()
// Desc : GUI Utente
// Todo : Nulla ;)
//------------------------------------------

int menu(){
int scelta = 0;
std::cout<<std::endl;
std::cout<<"Digita la voce desiderata e premi invio"<<std::endl;
std::cout<<"1.Individua il Proprio Processore"<<std::endl;
std::cout<<"2.Run BenchMark"<<std::endl;;
std::cout<<"0.Fine"<<std::endl;
std::cout<<std::endl;
std::cin>>scelta;
return scelta;
}
//-----------------------------
// Name : Percentuale
// Desc : Calcola la percentuale di avanzamento
// ToDo : Implementarla
//----------------------------------------------
double percentuale (int campionatura) {
double unpercento = 0;
unpercento = (double)100/campionatura;
return unpercento;
}


void savefile (float punt){
if ((file = fopen("punteggio.txt","r"))==NULL){
if ((file = fopen("punteggio.txt","a"))==NULL)
exit (1);
else
fprintf(file," .....:::::CPU Speed Beta 0.1 Powered Valerio Bignardi Alias Eni:::::.....\n\n");
#if defined __linux__
fprintf(file,"OS rilevato: linux\n");
#elif defined WIN32
fprintf(file,"OS rilevato: Windows\n");
#endif
run = true; // Impostando a True il valore di run, printregs non comunichera a schermo il valore di string
for(int j=0x80000002;j<=0x80000004;j++){
unsigned long eax,ebx,ecx,edx;
cpuid(j,eax,ebx,ecx,edx);
printregs(eax,ebx,ecx,edx);
}
fprintf(file,"\n");
fprintf(file,"Punteggio: %.0f\n",punt);
fprintf(file,"=================================================\n");
run = false;
}else{
if ((file = fopen("punteggio.txt","a"))==NULL)
exit (1);
#if defined __linux__
fprintf(file,"OS rilevato: linux\n");
#elif defined WIN32
fprintf(file,"OS rilevato: Windows\n");
#endif
run = true;
for(int j=0x80000002;j<=0x80000004;j++){
unsigned long eax,ebx,ecx,edx;
cpuid(j,eax,ebx,ecx,edx);
printregs(eax,ebx,ecx,edx);
}
fprintf(file,"\n");
fprintf(file,"Punteggio: %.0f\n",punt);
fprintf(file,"=================================================\n");
run = false; //reimposto a false il valore di run cosi printregs puo nuovamente stampare a schermo
fclose(file);
}
}//end save


void grafico() {
std::cout<<std::endl;
std::cout<<"\t\t Tabella di cofronto risultati"<<std::endl;
std::cout<<std::endl;
std::cout<<"LEGENDA: # x 2000 punti"<<std::endl;
std::cout<<std::endl;
std::cout<<"Processore \t Risultato \t Istogramma"<<std::endl;
std::cout<<"---------------------------------------------------------------------"<<std::endl;
for (int i = 0;i<25;i++){
if (i == 3){
std::cout<<"Pentium M 1.4 Ghz | 26642 punti |";
std::cout<<" ";
for (int o = 1; o <= (26642/2000);o++)
std::cout<<"#";
std::cout<<std::endl;
}
if (i == 6)
std::cout<<"----------------------------------------------------------------------"<<std::endl;
if (i == 9){
std::cout<<"AMD AthlonXP 2100+ | 36356 punti |";
std::cout<<" ";
for (int o = 1; o <= (36356/2000);o++)
std::cout<<"#";
std::cout<<std::endl;
}
if (i == 12)
std::cout<<"----------------------------------------------------------------------"<<std::endl;
if (i == 15){
std::cout<<"AMD AthlonXP 3200+ | 47665 punti |";
std::cout<<" ";
for (int o = 1; o <= (47665/2000);o++)
std::cout<<"#";
std::cout<<std::endl;
}
if (i == 17)
std::cout<<"----------------------------------------------------------------------"<<std::endl;
if (i == 20)
std::cout<<"Tuo processore |\t | \t "<<std::endl;
if (i == 21){
for(int j=0x80000002;j<=0x80000004;j++){
unsigned long eax,ebx,ecx,edx;
cpuid(j,eax,ebx,ecx,edx);
printregs(eax,ebx,ecx,edx);
}
std::cout<<" | "<<punteggio<<" punti |";
std::cout<<" ";
for (int o = 1; o <= (punteggio/2000);o++)
std::cout<<"#";
std::cout<<std::endl;
}//end for
std::cout<<" |\t | \t "<<std::endl;
}
std::cout<<"----------------------------------------------------------------------"<<std::endl;
}


////////////////////////////////////////////////////////////
// Calcolo BenchMark
///////////////////////////////////////////////////////////
//-------------------------------------------------
// Name : Random
// Desc : Genera Numeri Casuali
// ToDo : Nulla
//-------------------------------------------------
double Random()
{
double lo, hi, test;
hi = ceil(seed / Q);
lo = seed - Q * hi;
test = A * lo - R * hi;
if (test < 0.0) {
seed = test + M;
} else {
seed = test;
} /* endif */
return seed / M;
} //end random

//-----------------------------------------
// Name : Creavett
// Desc : Genera i vettori da ordinare
//-----------------------------------------

void creavett(){
for (int i=0; i<max;i++)
vettore[i] =(long)( Random()*500000);
}


//--------------------------------------------------------------------------------
// Name : swap(long& a, long& b)
// Desc : Questa funzione implementa lo scambio dei valori con
// la tecnica inplace, ovverosia senza alcuna variabile di supporto
// Si noti che i parametri sono passati per riferimento, altrimenti
// le modifiche sarebbero effettuate su copie di essi, e lo scambio di valore non ci sarebbe.
// ^= è il simbolo di Xor. Eseguo un Xor per scambiare i valori
// ToDo : Nulla :D
// Vers : 1.0
//----------------------------------------------------------------------------------------

void swap (long& a, long& b) {
a ^= b ^= a ^= b; //Metodo inplace per scambiare i valori di a e b
};

////////////////////////////////////////////////////////////////////////////////
// QUICKSORT
////////////////////////////////////////////////////////////////////////////////

//-----------------------------------------------------------------------
// Name : Partition
// Desc : Prende come parametri puntatore ad un vettore, indice sinistro ,indice destro
// Inizia a scorrerre il vettore partendo da fuori il vettore
// e inizia un loop ke continua fino a quando l'indice sx è minore dell'indice dx
// Dentro al loop viene fatto scorrere il vettore e ogni singolo elemento del vettore
// viene confrontato con il pivot e se maggiore viene messo a dx se inferiore viene
// posizionato a sx tramite la funzione swap
// ToDo : Nulla
// Vers : 1.0
// Bugs : N.P.
//-----------------------------------------------------------------------------------------

int Partition (long* vett,int left,int right){
pivot = vett[left];//a pivot assegno il primo elemento
i = left - 1 ; //inizio da fuori il vettore
j = right + 1; //inizio da fuori il vettore
//fino a quando l indice inferiore non supera l indice superiore continua a cercare gli elementi
while (i < j){
do{j--;} //decrementa di una posizione l'indice superiore
while (vett[j]>pivot); //continua a decrementare fino a quando l elemento trovato nn è maggiore del pivot
do{
i++;
}while (vett[i]<pivot);//continua a decrementare fino a quando l elemento trovato nn è minore del pivot
if (i<j)
swap(vett[i],vett[j]);//inverti i due valori
else
return j;// se i ha superato j ritorno il nuovo pivot a Qsort
}//end while
}//end partition

//-------------------------------------------------------------
// Name : QuickSort
// Desc : Assegna un valore a al pivot q.la funzione richiama se stessa
// ricorsivamente passandosi prima l'albero di dx e poi quello di sx
// ToDO : Nulla :D
// Vers : 1.0
// Bugs : N.P
//-----------------------------------------------------------

void QuickSort (long* vett,int left,int right){
if (left < right){
q = Partition (vett,left,right); //Assegnazione pivot
QuickSort(vett,left,q);//albero di sinistra
QuickSort(vett,q+1,right);//albero di destra
}//end if

}//end quicksort



long int Tara (){
t2 = 0;
t3 = 0;
t2 = clock();
creavett();
t3 = clock();
return (t3 - t2);
}
//----------------------------------------------
// Name : exec ()
// Desc : Richiama la funzione quicksort e Calcola il tempo
// impiegato e il numero di volte in cui è stato ordinato il vettore
// Nel Tempi minimo (Tmin) Richiesto
// ToDo : Nothing ;D
//-----------------------------------------------------------

int exec() {
int t = 0;
t0 = clock();
do{
creavett();//creo un nuovo vettore da ordinare
QuickSort(vettore,0,(max - 1)); // richiamo QuickSort
t++; //incremento il contatore
t1 = clock();
tot = (t1 - t0) - Tara();
tot_effettivo = tot;
tot_sec = (double)tot_effettivo/CLOCKS_PER_SEC;

}while (tot_sec < Tmin );
//std::cout<<"Il punteggio effettuato e': "<<t<<std::endl;
return t;
}//End exec


//-----------------------------------
// Name : BenchMark
// Desc : Esegue un numero di volte pari a campioni la funzione exec
// Questo per avere un VALORE MEDIO del punteggio ottenuto
// ToDo : Nulla
//------------------------------------------------------------
void BenchMark (){
long punteggio_parz = 0;
perc = 0;
//pulisco lo schermo
#if defined __linux__
system("clear");
std::cout<<"OS: Linux"<<std::endl;
#elif defined WIN32
system("cls");
std::cout<<"OS: Windows"<<std::endl;
#endif
for(int j=0x80000002;j<=0x80000004;j++){
unsigned long eax,ebx,ecx,edx;
cpuid(j,eax,ebx,ecx,edx);
printregs(eax,ebx,ecx,edx);
}
std::cout<<std::endl;
std::cout<<"Progresso: "<<perc<<" %"<<std::endl; //inizializzo a schermo il progresso
for (int j=0;j<campioni;j++){
punteggio_parz += exec();// eseguo l ordinamento
//faccio un refresh dello della percentuale
#if defined __linux__
system("clear");
std::cout<<"OS: Linux"<<std::endl;
#elif defined WIN32
system("cls");
std::cout<<"OS: Windows"<<std::endl;
#endif
for(int j=0x80000002;j<=0x80000004;j++){
unsigned long eax,ebx,ecx,edx;
cpuid(j,eax,ebx,ecx,edx);
printregs(eax,ebx,ecx,edx);
}
perc += percentuale(campioni);
std::cout<<std::endl;
std::cout<<"Progresso: "<<perc<<" %"<<std::endl;// aggiorno percentuale attuale
}//end for
punteggio = punteggio_parz / campioni; //calcolo il punteggio medio ottenuto
std::cout<<"il punteggio ottenuto e': "<< punteggio <<std::endl; //comunico a schermo il risultato
savefile(punteggio);
}

//-----------------------------------
// Name : cpu_id
// Desc : Identifica il processore
//--------------------------------------

void cpu_id(){

/* Insert code here to test if CPUID instruction is available */

/* Dump all the CPUID results in raw hex */
cpuid(0,maxi,unused,unused,unused);
maxi &= 0xffff; /* The high-order word is non-zero on some Cyrix CPUs */
//Stampa contenuto eax ebx ecx edx
/* printf(" eax in eax ebx ecx edx\n");
for(i=0;i<=maxi;i++){
unsigned long eax,ebx,ecx,edx;

cpuid(i,eax,ebx,ecx,edx);
printf("%08x %08lx %08lx %08lx %08lx\n",i,eax,ebx,ecx,edx);
}*/
cpuid(0x80000000,maxei,unused,unused,unused);
/* for(li=0x80000000;li<=maxei;li++){
unsigned long eax,ebx,ecx,edx;

cpuid(li,eax,ebx,ecx,edx);
printf("%08lx %08lx %08lx %08lx %08lx\n",li,eax,ebx,ecx,edx);
}*/
printf("\n");

/* Vendor ID and max CPUID level supported */
cpuid(0,unused,ebx,ecx,edx);
printf("Vendor ID: \"");
for(i=0;i<4;i++)
putchar(ebx >> (8*i));
for(i=0;i<4;i++)
putchar(edx >> (8*i));
for(i=0;i<4;i++)
putchar(ecx >> (8*i));
printf("\"; CPUID level %ld\n\n",maxi);


switch(ebx){
case 0x756e6547: /* Intel */
dointel(maxi);
break;
case 0x68747541: /* AMD */
doamd(maxi);
break;
case 0x69727943: /* Cyrix */
docyrix(maxi);
break;
default:
printf("Unknown vendor\n");
break;
}
}//End cpu_id
//-------------------------------
// Name : Main
// Desc : Il main richiama le funzioni necessarie per il BenchMark e per l'identificazione del
// Processore
// ToDo : Salvare su file
//--------------------------------------------------------------------------

int main(){
seed = 123456789;
std::cout<<"\t\t\t Speed Cpu Test beta 0.1";
std::cout<<std::endl;
std::cout<<"\t\t Programma Di Valerio Bignardi"<<std::endl;
std::cout<<std::endl;
#if defined __linux__
std::cout<<"\t\t\t OS Rilevato: linux"<<std::endl;
#elif defined WIN32
std::cout<<"\t\t\t OS Rilevato: Win32"<<std::endl;
#endif

int scelta = 0;

do{
scelta = menu();
switch (scelta){
case 1: cpu_id() ;break;
case 2: BenchMark(); grafico();break;
case 0: exit (0);break;

}//End switch
}while (scelta != 0);
}// end main



//////////////////////////////////////////////////////////
// Identificazione CPU e Features
//////////////////////////////////////////////////////////
char *Intel_feature_flags[] = {
"FPU Floating Point Unit",
"VME Virtual 8086 Mode Enhancements",
"DE Debugging Extensions",
"PSE Page Size Extensions",
"TSC Time Stamp Counter",
"MSR Model Specific Registers",
"PAE Physical Address Extension",
"MCE Machine Check Exception",
"CX8 COMPXCHG8B Instruction",
"APIC On-chip Advanced Programmable Interrupt Controller present and enabled",
"10 Reserved",
"SEP Fast System Call",
"MTRR Memory Type Range Registers",
"PGE PTE Global Flag",
"MCA Machine Check Architecture",
"CMOV Conditional Move and Compare Instructions",
"FGPAT Page Attribute Table",
"PSE-36 36-bit Page Size Extension",
"PN Processor Serial Number present and enabled",
"CLFSH CFLUSH instruction",
"20 reserved",
"DS Debug store",
"ACPI Thermal Monitor and Clock Ctrl",
"MMX MMX instruction set",
"FXSR Fast FP/MMX Streaming SIMD Extensions save/restore",
"SSE Streaming SIMD Extensions instruction set",
"SSE2 SSE2 extensions",
"SS Self Snoop",
"HT Hyper Threading",
"TM Thermal monitor",
"30 reserved",
"31 reserved",
};

/* Intel-specific information */
void dointel(int maxi){
printf("Intel-specific functions:\n");

if(maxi >= 1){
/* Family/model/type etc */
int clf,apic_id,feature_flags;
int extended_model = -1,extended_family = -1;
unsigned long eax,ebx,edx,unused;
int stepping,model,family,type,reserved,brand,siblings;
int i;

cpuid(1,eax,ebx,unused,edx);
printf("Version %08lx:\n",eax);
stepping = eax & 0xf;
model = (eax >> 4) & 0xf;
family = (eax >> 8) & 0xf;
type = (eax >> 12) & 0x3;
reserved = eax >> 14;
clf = (ebx >> 8) & 0xff;
apic_id = (ebx >> 24) & 0xff;
siblings = (ebx >> 16) & 0xff;
feature_flags = edx;

printf("Type %d - ",type);
switch(type){
case 0:
printf("Original OEM");
break;
case 1:
printf("Overdrive");
break;
case 2:
printf("Dual-capable");
break;
case 3:
printf("Reserved");
break;
}
printf("\n");

printf("Family %d - ",family);
switch(family){
case 3:
printf("i386");
break;
case 4:
printf("i486");
break;
case 5:
printf("Pentium");
break;
case 6:
printf("Pentium Pro");
break;
case 15:
printf("Pentium 4");
}
printf("\n");
if(family == 15){
extended_family = (eax >> 20) & 0xff;
printf("Extended family %d\n",extended_family);
}
printf("Model %d - ",model);
switch(family){
case 3:
break;
case 4:
switch(model){
case 0:
case 1:
printf("DX");
break;
case 2:
printf("SX");
break;
case 3:
printf("487/DX2");
break;
case 4:
printf("SL");
break;
case 5:
printf("SX2");
break;
case 7:
printf("write-back enhanced DX2");
break;
case 8:
printf("DX4");
break;
}
break;
case 5:
switch(model){
case 1:
printf("60/66");
break;
case 2:
printf("75-200");
break;
case 3:
printf("for 486 system");
break;
case 4:
printf("MMX");
break;
}
break;
case 6:
switch(model){
case 1:
printf("Pentium Pro");
break;
case 3:
printf("Pentium II Model 3");
break;
case 5:
printf("Pentium II Model 5/Xeon/Celeron");
break;
case 6:
printf("Celeron");
break;
case 7:
printf("Pentium III/Pentium III Xeon - external L2 cache");
break;
case 8:
printf("Pentium III/Pentium III Xeon - internal L2 cache");
break;
}
break;
case 15:
break;
}
printf("\n");
if(model == 15){
extended_model = (eax >> 16) & 0xf;
printf("Extended model %d\n",extended_model);
}
printf("Stepping %d\n",stepping);

printf("Reserved %d\n\n",reserved);

brand = ebx & 0xff;
if(brand > 0){
printf("Brand index: %d [",brand);
if(brand < MAXBRANDS){
printf("%s]\n",Brands[brand]);
} else {
printf("not in table]\n");
}
}
cpuid(0x80000000,eax,ebx,unused,edx);
if(eax & 0x80000000){
/* Extended feature/signature bits supported */
int maxe = eax;
if(maxe >= 0x80000004){
int i;

printf("Extended brand string: \"");
for(i=0x80000002;i<=0x80000004;i++){
unsigned long eax,ebx,ecx,edx;

cpuid(i,eax,ebx,ecx,edx);
printregs(eax,ebx,ecx,edx);
}
printf("\"\n");
}
}
if(clf)
printf("CLFLUSH instruction cache line size: %d\n",clf);

if(apic_id)
printf("Initial APIC ID: %d\n",apic_id);

if(feature_flags & (1<<28)){
printf("Hyper threading siblings: %d\n",siblings);
}

printf("\nFeature flags %08x:\n",feature_flags);
for(i=0;i<32;i++){
if(feature_flags & (1<<i)){
printf("%s\n",Intel_feature_flags[i]);
}
}
printf("\n");
}
if(maxi >= 2){
/* Decode TLB and cache info */
int ntlb,i;

ntlb = 255;
printf("TLB and cache info:\n");
for(i=0;i<ntlb;i++){
unsigned long eax,ebx,ecx,edx;

cpuid(2,eax,ebx,ecx,edx);
ntlb = eax & 0xff;
decode_intel_tlb(eax >> 8);
decode_intel_tlb(eax >> 16);
decode_intel_tlb(eax >> 24);

if((ebx & 0x80000000) == 0){
decode_intel_tlb(ebx);
decode_intel_tlb(ebx >> 8);
decode_intel_tlb(ebx >> 16);
decode_intel_tlb(ebx >> 24);
}
if((ecx & 0x80000000) == 0){
decode_intel_tlb(ecx);
decode_intel_tlb(ecx >> 8);
decode_intel_tlb(ecx >> 16);
decode_intel_tlb(ecx >> 24);
}
if((edx & 0x80000000) == 0){
decode_intel_tlb(edx);
decode_intel_tlb(edx >> 8);
decode_intel_tlb(edx >> 16);
decode_intel_tlb(edx >> 24);
}
}
}
if(maxi >= 3){
/* Pentium III CPU serial number */
unsigned long signature,unused,ecx,edx;

cpuid(1,signature,unused,unused,unused);
cpuid(3,unused,unused,ecx,edx);
printf("Processor serial: ");
printf("%04lX",signature >> 16);
printf("-%04lX",signature & 0xffff);
printf("-%04lX",edx >> 16);
printf("-%04lX",edx & 0xffff);
printf("-%04lX",ecx >> 16);
printf("-%04lX\n",ecx & 0xffff);
}
}
void printregs(int eax,int ebx,int ecx,int edx){
int j;

string[16] = '\0';
for(j=0;j<4;j++){
string[j] = eax >> (8*j);
string[j+4] = ebx >> (8*j);
string[j+8] = ecx >> (8*j);
string[j+12] = edx >> (8*j);
}

if (run == false)
printf("%s",string);
else
fprintf(file,"%s",string);
}


/* Decode Intel TLB and cache info descriptors */
void decode_intel_tlb(int x){
x &= 0xff;
if(x != 0)
printf("%02x: ",x);
switch(x){
case 0:
break;
case 0x1:
printf("Instruction TLB: 4KB pages, 4-way set assoc, 32 entries\n");
break;
case 0x2:
printf("Instruction TLB: 4MB pages, 4-way set assoc, 2 entries\n");
break;
case 0x3:
printf("Data TLB: 4KB pages, 4-way set assoc, 64 entries\n");
break;
case 0x4:
printf("Data TLB: 4MB pages, 4-way set assoc, 8 entries\n");
break;
case 0x6:
printf("1st-level instruction cache: 8KB, 4-way set assoc, 32 byte line size\n");
break;
case 0x8:
printf("1st-level instruction cache: 16KB, 4-way set assoc, 32 byte line size\n");
break;
case 0xa:
printf("1st-level data cache: 8KB, 2-way set assoc, 32 byte line size\n");
break;
case 0xc:
printf("1st-level data cache: 16KB, 4-way set assoc, 32 byte line size\n");
break;
case 0x40:
printf("No 2nd-level cache, or if 2nd-level cache exists, no 3rd-level cache\n");
break;
case 0x41:
printf("2nd-level cache: 128KB, 4-way set assoc, 32 byte line size\n");
break;
case 0x42:
printf("2nd-level cache: 256KB, 4-way set assoc, 32 byte line size\n");
break;
case 0x43:
printf("2nd-level cache: 512KB, 4-way set assoc, 32 byte line size\n");
break;
case 0x44:
printf("2nd-level cache: 1MB, 4-way set assoc, 32 byte line size\n");
break;
case 0x45:
printf("2nd-level cache: 2MB, 4-way set assoc, 32 byte line size\n");
break;
case 0x50:
printf("Instruction TLB: 4KB and 2MB or 4MB pages, 64 entries\n");
break;
case 0x51:
printf("Instruction TLB: 4KB and 2MB or 4MB pages, 128 entries\n");
break;
case 0x52:
printf("Instruction TLB: 4KB and 2MB or 4MB pages, 256 entries\n");
break;
case 0x5b:
printf("Data TLB: 4KB and 4MB pages, 64 entries\n");
break;
case 0x5c:
printf("Data TLB: 4KB and 4MB pages, 128 entries\n");
break;
case 0x5d:
printf("Data TLB: 4KB and 4MB pages, 256 entries\n");
break;
case 0x66:
printf("1st-level data cache: 8KB, 4-way set assoc, 64 byte line size\n");
break;
case 0x67:
printf("1st-level data cache: 16KB, 4-way set assoc, 64 byte line size\n");
break;
case 0x68:
printf("1st-level data cache: 32KB, 4-way set assoc, 64 byte line size\n");
break;
case 0x70:
printf("Trace cache: 12K-micro-op, 4-way set assoc\n");
break;
case 0x71:
printf("Trace cache: 16K-micro-op, 4-way set assoc\n");
break;
case 0x72:
printf("Trace cache: 32K-micro-op, 4-way set assoc\n");
break;
case 0x79:
printf("2nd-level cache: 128KB, 8-way set assoc, sectored, 64 byte line size\n");
break;
case 0x7a:
printf("2nd-level cache: 256KB, 8-way set assoc, sectored, 64 byte line size\n");
break;
case 0x7b:
printf("2nd-level cache: 512KB, 8-way set assoc, sectored, 64 byte line size\n");
break;
case 0x7c:
printf("2nd-level cache: 1MB, 8-way set assoc, sectored, 64 byte line size\n");
break;
case 0x82:
printf("2nd-level cache: 256KB, 8-way set assoc, 32 byte line size\n");
break;
case 0x83:
printf("2nd-level cache: 512KB, 8-way set assoc 32 byte line size\n");
break;
case 0x84:
printf("2nd-level cache: 1MB, 8-way set assoc, 32 byte line size\n");
break;
case 0x85:
printf("2nd-level cache: 2MB, 8-way set assoc, 32 byte line size\n");
break;
default:
printf("unknown TLB/cache descriptor\n");
break;
}
}
char *AMD_feature_flags[] = {
"Floating Point Unit",
"Virtual Mode Extensions",
"Debugging Extensions",
"Page Size Extensions",
"Time Stamp Counter (with RDTSC and CR4 disable bit)",
"Model Specific Registers with RDMSR & WRMSR",
"PAE - Page Address Extensions",
"Machine Check Exception",
"COMPXCHG8B Instruction",
"APIC",
"10 - Reserved",
"SYSCALL/SYSRET or SYSENTER/SYSEXIT instructions",
"MTRR - Memory Type Range Registers",
"Global paging extension",
"Machine Check Architecture",
"Conditional Move Instruction",
"PAT - Page Attribute Table",
"PSE-36 - Page Size Extensions",
"18 - reserved",
"19 - reserved",
"20 - reserved",
"21 - reserved",
"AMD MMX Instruction Extensions",
"MMX instructions",
"FXSAVE/FXRSTOR",
"25 - reserved",
"26 - reserved",
"27 - reserved",
"28 - reserved",
"29 - reserved",
"3DNow! Instruction Extensions",
"3DNow instructions",
};

char *Assoc[] = {
"L2 off",
"Direct mapped",
"2-way",
"reserved",
"4-way",
"reserved",
"8-way",
"reserved",
"16-way",
"reserved",
"reserved",
"reserved",
"reserved",
"reserved",
"reserved",
"full",
};



/* AMD-specific information */
void doamd(int maxi){
unsigned long maxei,unused;
int family = 0;

printf("AMD-specific functions\n");

/* Do standard stuff */
if(maxi >= 1){
unsigned long eax,ebx,edx,unused;
int stepping,model,reserved;

cpuid(1,eax,ebx,unused,edx);
stepping = eax & 0xf;
model = (eax >> 4) & 0xf;
family = (eax >> 8) & 0xf;
reserved = eax >> 12;

printf("Version %08lx:\n",eax);
// fprintf(file,"Version %08lx:\n",eax);
printf("Family: %d Model: %d [",family,model);
switch(family){
case 4:
printf("486 model %d",model);
break;
case 5:
switch(model){
case 0:
case 1:
case 2:
case 3:
case 6:
case 7:
printf("K6 Model %d",model);
break;
case 8:
printf("K6-2 Model 8");
break;
case 9:
printf("K6-III Model 9");
break;
default:
printf("K5/K6 model %d",model);
break;
}
break;
case 6:
switch(model){
case 1:
case 2:
case 4:
printf("Athlon model %d",model);
break;
case 3:
printf("Duron model 3");
break;
case 6:
printf("Athlon MP/Mobile Athlon model 6");
break;
case 7:
printf("Mobile Duron Model 7");
break;
default:
printf("Duron/Athlon model %d",model);
break;
}

break;
}
printf("]\n\n");
{
int i;

printf("Standard feature flags %08lx:\n",edx);
for(i=0;i<32;i++){
if(family == 5 && model == 0){
if(i == 9)
printf("Global Paging Extensions\n");
else if(i == 13)
printf("13 - reserved\n");
} else {
if(edx & (1<<i)){
printf("%s\n",AMD_feature_flags[i]);
}
}
}
}
}
/* Check for presence of extended info */
cpuid(0x80000000,maxei,unused,unused,unused);
if(maxei == 0)
return;

if(maxei >= 0x80000001){
unsigned long eax,ebx,ecx,edx;
int stepping,model,generation,reserved;
int i;

cpuid(0x80000001,eax,ebx,ecx,edx);
stepping = eax & 0xf;
model = (eax >> 4) & 0xf;
generation = (eax >> 8) & 0xf;
reserved = eax >> 12;

printf("Generation: %d Model: %d\n",generation,model);
printf("Extended feature flags %08lx:\n",edx);
for(i=0;i<32;i++){
if(family == 5 && model == 0 && i == 9){
printf("Global Paging Extensions\n");
} else {
if(edx & (1<<i)){
printf("%s\n",AMD_feature_flags[i]);
}
}
}
}
printf("\n");
if(maxei >= 0x80000002){
/* Processor identification string */
int j;
printf("Processor name string: ");
for(j=0x80000002;j<=0x80000004;j++){
unsigned long eax,ebx,ecx,edx;

cpuid(j,eax,ebx,ecx,edx);
printregs(eax,ebx,ecx,edx);
}
printf("\n");
}
if(maxei >= 0x80000005){
/* TLB and cache info */
unsigned long eax,ebx,ecx,edx;

cpuid(0x80000005,eax,ebx,ecx,edx);
printf("L1 Cache Information:\n");
if(family >= 6){
printf("2/4-MB Pages:\n");
printf(" Data TLB: associativity %ld-way #entries %ld\n",
(eax >> 24) & 0xff,(eax >> 16) & 0xff);
printf(" Instruction TLB: associativity %ld-way #entries %ld\n",
(eax >> 8) & 0xff,eax & 0xff);
}
printf("4-KB Pages:\n");
printf(" Data TLB: associativity %ld-way #entries %ld\n",
(ebx >> 24) & 0xff,(ebx >> 16) & 0xff);
printf(" Instruction TLB: associativity %ld-way #entries %ld\n",
(ebx >> 8) & 0xff,ebx & 0xff);

printf("L1 Data cache:\n");
printf(" size %ld KB associativity %lx-way lines per tag %ld line size %ld\n",
ecx >> 24,(ecx>>16) & 0xff,(ecx >> 8)&0xff,ecx&0xff);

printf("L1 Instruction cache:\n");
printf(" size %ld KB associativity %lx-way lines per tag %ld line size %ld\n",
edx >> 24,(edx>>16) & 0xff,(edx >> 8)&0xff,edx&0xff);
printf("\n");
}

/* check K6-III (and later?) on-chip L2 cache size */
if (maxei >= 0x80000006) {
unsigned long eax,ebx,ecx,unused;
int assoc;

cpuid(0x80000006,eax,ebx,ecx,unused);
printf("L2 Cache Information:\n");
if(family >= 6){
printf("2/4-MB Pages:\n");
assoc = (eax >> 24) & 0xff;
if(assoc == 6)
assoc = 8;
printf(" Data TLB: associativity %s #entries %ld\n",
Assoc[(eax >> 24) & 0xf],(eax >> 16) & 0xff);
assoc = (eax >> 16) & 0xff;
printf(" Instruction TLB: associativity %s #entries %ld\n",
Assoc[(eax >> 8) & 0xf],eax & 0xff);

printf("4-KB Pages:\n");
printf(" Data TLB: associativity %s #entries %ld\n",
Assoc[(ebx >> 24) & 0xf],(ebx >> 16) & 0xff);
printf(" Instruction TLB: associativity %s #entries %ld\n",
Assoc[(ebx >> 8) & 0xf],ebx & 0xff);
}
printf(" size %ld KB associativity %s lines per tag %ld line size %ld\n",
ecx >> 24,Assoc[(ecx>>16) & 0xf],(ecx >> 8)&0xff,ecx&0xff);

printf("\n");
}
/* Check power management feature flags */
if(maxei >= 0x80000007){
unsigned long unused,edx;

printf("Advanced Power Management Feature Flags\n");
cpuid(0x80000007,unused,unused,unused,edx);
if(edx & 1)
printf("Has temperature sensing diode\n");
if(edx & 2)
printf("Supports Frequency ID control\n");
if(edx & 4)
printf("Supports Voltage ID control\n");
}
/* Check phys address & linear address size */
if(maxei >= 0x80000008){
unsigned long unused,eax;

cpuid(0x80000008,eax,unused,unused,unused);
printf("Maximum linear address: %ld; maximum phys address %ld\n",
(eax>>8) & 0xff,eax&0xff);
}
}

char *Cyrix_standard_feature_flags_5[] = {
"FPU Floating Point Unit",
"V86 Virtual Mode Extensions",
"Debug Extension",
"4MB Page Size",
"Time Stamp Counter",
"RDMSR/WRMSR (Model Specific Registers)",
"PAE",
"Machine Check Exception",
"COMPXCHG8B Instruction",
"APIC - On-chip Advanced Programmable Interrupt Controller present and enabled",
"10 - Reserved",
"11 - Reserved",
"MTRR Memory Type Range Registers",
"13 - reserved",
"Machine Check",
"CMOV Conditional Move Instruction",
"16 - reserved",
"17 - reserved",
"18 - reserved",
"19 - reserved",
"20 - reserved",
"21 - reserved",
"22 - reserved",
"MMX instructions",
"24 - reserved",
"25 - reserved",
"26 - reserved",
"27 - reserved",
"28 - reserved",
"29 - reserved",
"30 - reserved",
};

char *Cyrix_standard_feature_flags_not5[] = {
"FPU Floating Point Unit",
"V86 Virtual Mode Extensions",
"Debug Extension",
"4MB Page Size",
"Time Stamp Counter",
"RDMSR/WRMSR (Model Specific Registers)",
"PAE",
"Machine Check Exception",
"COMPXCHG8B Instruction",
"APIC - On-chip Advanced Programmable Interrupt Controller present and enabled",
"10 - Reserved",
"11 - Reserved",
"MTRR Memory Type Range Registers",
"Global Paging Extension",
"Machine Check",
"CMOV Conditional Move Instruction",
"16 - reserved",
"17 - reserved",
"18 - reserved",
"19 - reserved",
"20 - reserved",
"21 - reserved",
"22 - reserved",
"MMX instructions",
"24 - reserved",
"25 - reserved",
"26 - reserved",
"27 - reserved",
"28 - reserved",
"29 - reserved",
"30 - reserved",
};


char *Cyrix_extended_feature_flags[] = {
"FPU Floating Point Unit",
"V86 Virtual Mode Extensions",
"Debug Extension",
"Page Size Extensions",
"Time Stamp Counter",
"Cyrix MSR",
"PAE",
"MC Exception",
"COMPXCHG8B",
"APIC on chip",
"SYSCALL/SYSRET",
"11 - reserved",
"MTRR",
"Global bit",
"Machine Check",
"CMOV",
"FPU CMOV",
"17 - reserved",
"18 - reserved",
"19 - reserved",
"20 - reserved",
"21 - reserved",
"22 - reserved",
"MMX",
"Extended MMX",
"25 - reserved",
"26 - reserved",
"27 - reserved",
"28 - reserved",
"29 - reserved",
"30 - reserved",
"3DNow instructions",
};

/* Cyrix-specific information */
void docyrix(int maxi){
unsigned long maxei,unused;
int i;

printf("Cyrix-specific functions\n");
cpuid(0x80000000,maxei,unused,unused,unused);
/* Dump extended info, if any, in raw hex */
for(i=0x80000000;i<=maxei;i++){
unsigned long eax,ebx,ecx,edx;

cpuid(i,eax,ebx,ecx,edx);
printf("eax in: 0x%x, eax = %08lx ebx = %08lx ecx = %08lx edx = %08lx\n",i,eax,ebx,ecx,edx);
}

/* Do standard stuff */
if(maxi >= 1){
unsigned long eax,unused,edx;
int stepping,model,family,reserved;

cpuid(1,eax,unused,unused,edx);
stepping = eax & 0xf;
model = (eax >> 4) & 0xf;
family = (eax >> 8) & 0xf;
reserved = eax >> 12;

printf("Family: %d Model: %d [",family,model);
switch(family){
case 4:
switch(model){
case 4:
printf("MediaGX");
break;
}
break;
case 5:
switch(model){
case 2:
printf("6x86");
break;
case 4:
printf("BXm");
break;
}
break;
case 6:
switch(model){
case 0:
printf("6x86/MX");
break;
}
break;
}
printf("]\n\n");
if(family == 5 && model == 0){
int i;

for(i=0;i<32;i++){
if(edx & (1<<i)){
printf("%s\n",Cyrix_standard_feature_flags_5[i]);
}
}
} else {
int i;

for(i=0;i<32;i++){
if(edx & (1<<i)){
printf("%s\n",Cyrix_standard_feature_flags_not5[i]);
}
}
}
}
if(maxi >= 2){
/* TLB and L1 Cache info */
int ntlb = 255;
int i;

for(i=0;i<ntlb;i++){
unsigned long eax,edx,unused;

cpuid(2,eax,unused,unused,edx);
ntlb = eax & 0xff;
decode_cyrix_tlb(eax >> 8);
decode_cyrix_tlb(eax >> 16);
decode_cyrix_tlb(eax >> 24);

/* ebx and ecx are reserved */

if((edx & 0x80000000) == 0){
decode_cyrix_tlb(edx);
decode_cyrix_tlb(edx >> 8);
decode_cyrix_tlb(edx >> 16);
decode_cyrix_tlb(edx >> 24);
}
}
}

/* Check for presence of extended info */
if(maxei < 0x80000000)
return;

printf("\nExtended info:\n");
if(maxei >= 0x80000001){
unsigned long eax,ebx,ecx,edx;
int stepping,model,family,reserved,i;

cpuid(0x80000001,eax,ebx,ecx,edx);
stepping = eax & 0xf;
model = (eax >> 4) & 0xf;
family = (eax >> 8) & 0xf;
reserved = eax >> 12;
printf("Family: %d Model: %d [",family,model);
switch(family){
case 4:
printf("MediaGX");
break;
case 5:
printf("6x86/GXm");
break;
case 6:
printf("6x86/MX");
}
printf("]\n\n");

printf("Extended feature flags:\n");
for(i=0;i<32;i++){
if(edx & (1<<i)){
printf("%s\n",Cyrix_extended_feature_flags[i]);
}
}
}
printf("\n");
if(maxei >= 0x80000002){
/* Processor identification string */
char namestring[49],*cp;
int j;
cp = namestring;
printf("Processor name string: ");
for(j=0x80000002;j<=0x80000004;j++){
unsigned long eax,ebx,ecx,edx;

cpuid(j,eax,ebx,ecx,edx);
printregs(eax,ebx,ecx,edx);
}
}
if(maxei >= 0x80000005){
/* TLB and L1 Cache info */
int ntlb = 255;
int i;

for(i=0;i<ntlb;i++){
unsigned long eax,ebx,ecx,unused;

cpuid(0x80000005,eax,ebx,ecx,unused);
ntlb = eax & 0xff;
decode_cyrix_tlb(ebx >> 8);
decode_cyrix_tlb(ebx >> 16);
decode_cyrix_tlb(ebx >> 24);

/* eax and edx are reserved */

if((ecx & 0x80000000) == 0){
decode_cyrix_tlb(ecx);
decode_cyrix_tlb(ecx >> 8);
decode_cyrix_tlb(ecx >> 16);
decode_cyrix_tlb(ecx >> 24);
}
}
}
}


/* Decode Cyrix TLB and cache info descriptors */
void decode_cyrix_tlb(int x){
switch(x & 0xff){
case 0:
break;
case 0x70:
printf("TLB: 32 entries 4-way associative 4KB pages\n");
break;
case 0x80:
printf("L1 Cache: 16KB 4-way associative 16 bytes/line\n");
break;
}

}


ecco ora il programma è completo ..per favore qualcuno ke ha delle configurazioni differenti da quelle presenti nel programma , puo postare i risultati del benchmark,cosi posso creare una scala piu vasta di paragoni da mettere come istogramma
GRAZIE A TUTTI!

cionci
03-05-2005, 18:48
Ma se generi in random i vettori da ordinare come puoi pensare che questo sia un benchmark per la CPU ? Se ogni volta che esegui il codice i vettori sono diversi è chiaro che i risultati non saranno bilanciati...

Luc@s
03-05-2005, 20:09
.....:::::CPU Speed Beta 0.1 Powered Valerio Bignardi Alias Eni:::::.....

OS rilevato: Windows
AMD Athlon(tm) XP 2600+
Punteggio: 68356
=================================================


se ti puo servire....

3nigma666
03-05-2005, 20:40
la questione è solo 1 ,se ordino sempre lo stesso vettore,nn saro mai nella condizione ottimale per stimare ,la "velocita" della cpu,in quanto puo esserci il caso in cui mi capita un vettore gia ordinato al contrario (caso peggiore) e di conseguenza avro un solo risultato ,il risultato peggiore,in uanto il tempo di ordinamento è stato piu lunngo.Se invece creo in ogni iterazione un vettore differente,mi potra capitare il vettore gia ordinato correttamente,come anke il vettore gia ordinato al contrario,e come in fine i lcaso medio,il vettore completamente disordinato,questo mi permette di poter calcolare una media ,ke a mio parere risulta essere ilvalore statisticamente piu valido

71104
04-05-2005, 08:18
se vuoi creare un vero benchmark per la cpu, allora fai un programma che in un vettore di N interi trova il sottovettore di peso massimo, cioè quello la cui somma di tutti gli elementi è massima (non corrisponde a tutto il vettore stesso perché nel vettore ci sono anche numeri negativi); il mio professore di Programmazione II è riuscito a fare in C un algoritmo (funzionante!!!) con UN SOLO CICLO FOR... :eek: :mc:
ovviamente non devi arrivare ad una tale ottimizzazione se vuoi fare il benchmark :D l'algoritmo che avevo fatto io andava benissimo per testare la velocità della cpu (erano due for, uno dentro l'altro, più un altro po' di roba)

71104
04-05-2005, 08:29
aggiungo: io avevo fatto varie versioni del mio algoritmo ottimizzandole sempre di più (e ancora non ho raggiunto l'ottimizzazione massima: si potrebbero fare ancora altri miglioramenti), ma la migliore versione che sono riuscito a fare inizia a stare in crisi sui 40000 elementi (1 sec. sul mio Celeron da 3 giga e rotti) per poi diventare eccessivamente pesante sui 100000 (tra i 15 e i 20 sec.); l'algoritmo del prof per metterlo in difficoltà bisogna superare il milione di elementi :eek:, cioè ci vuole quasi più tempo per allocare il vettore ed inizializzarlo completamente che per eseguire il suo algoritmo... :eek: ci mette 1 sec (sempre sullo stesso processore) con 20 milioni :mc: e 5 sec con 50 milioni...

EDIT: e ovviamente funziona; certo, non posso averne la certezza visto che con quelle cifre non posso confrontare i risultati con altri algoritmi che si impallerebbero, però fino a 2000 elementi ho provato a fare i confronti con altri due miei algoritmi (versioni + o - ottimizzate del mio algoritmo) e i risultati coincidevano sempre.

cionci
04-05-2005, 08:30
IMHO se vuoi stimare le performance non puoi mai rivolgerti al caso...

Quindi preparati un file esterno in cui salvi i numeri estratti (che verranno caricati in emmoria ad ogni avvio)... Poi tramite un algoritmo che ti dovrai inventare te ad ogni ciclo più esterno prendi un sottogruppo dei numeri estratti per formare il vettore da ordinare... Ovviamente il tuo algoritmo deve creare sempre la stessa serie di vettori a partire dallo stesso file...

Ad esempio, quello più semplice che mi viene in mente è: salvi 1.000.000 di interi nel file... Ne prendi 100.000 alla volta... Cominci dal primo fino 100.000esimo...ed ordini... Poi passi dal secondo al 100.001esimo...e così via... Hai 1.000.000 di vettori diversi (quando arrivi agli ultimi 99.000 devi ricominciare a leggere dall'inizio del file i numeri mancanti)...

Qui parlo di file, ma il vettore con gli interi contenuti nel file te lo devi caricare in memoria... Inoltre questo permetterebbe di stimare anche il trasferimento a blocchi...

cionci
04-05-2005, 08:31
se vuoi creare un vero benchmark per la cpu, allora fai un programma che in un vettore di N interi trova il sottovettore di peso massimo, cioè quello la cui somma di tutti gli elementi è massima (non corrisponde a tutto il vettore stesso perché nel vettore ci sono anche numeri negativi); il mio professore di Programmazione II è riuscito a fare in C un algoritmo (funzionante!!!) con UN SOLO CICLO FOR... :eek: :mc:
ovviamente non devi arrivare ad una tale ottimizzazione se vuoi fare il benchmark :D l'algoritmo che avevo fatto io andava benissimo per testare la velocità della cpu (erano due for, uno dentro l'altro, più un altro po' di roba)
Scusa...non ho capito molto bene...non basta prendere i numeri maggiori di zero ?

cionci
04-05-2005, 08:33
Comnque per testare i vari aspetti di un CPU (cache, interfaccia con la memoria, floating point, interi e così via) non basta certo un algoritmo di ordinamento...in quanto è fortemente dipendente dall'itnerfaccia con la memoria... Invece algoritmi interessanti per le capacità di calcolo sono i frattali...

71104
04-05-2005, 08:33
Scusa...non ho capito molto bene...non basta prendere i numeri maggiori di zero ?
che ci fai coi numeri maggiori di 0? prendi ad esempio questo vettore:
-5 10 -4 11
sai dirmi qual è il sottovettore di peso massimo?

71104
04-05-2005, 08:35
ho dimenticato di specificare che l'algoritmo (sia il mio che quello del prof) non deve trovare la posizione d'inizio e fine del sottovettore cercato, ma solamente il peso; nell'esempio precedente il risultato doveva essere 17.

cionci
04-05-2005, 08:40
che ci fai coi numeri maggiori di 0? prendi ad esempio questo vettore:
-5 10 -4 11
sai dirmi qual è il sottovettore di peso massimo?
Ah...ma per sottovettore intendi contiguo...

cionci
04-05-2005, 08:42
Se te lo faccio con un solo for quanto mi dai ?

^TiGeRShArK^
04-05-2005, 09:19
IMHO se vuoi stimare le performance non puoi mai rivolgerti al caso...

Quindi preparati un file esterno in cui salvi i numeri estratti (che verranno caricati in emmoria ad ogni avvio)... Poi tramite un algoritmo che ti dovrai inventare te ad ogni ciclo più esterno prendi un sottogruppo dei numeri estratti per formare il vettore da ordinare... Ovviamente il tuo algoritmo deve creare sempre la stessa serie di vettori a partire dallo stesso file...

Ad esempio, quello più semplice che mi viene in mente è: salvi 1.000.000 di interi nel file... Ne prendi 100.000 alla volta... Cominci dal primo fino 100.000esimo...ed ordini... Poi passi dal secondo al 100.001esimo...e così via... Hai 1.000.000 di vettori diversi (quando arrivi agli ultimi 99.000 devi ricominciare a leggere dall'inizio del file i numeri mancanti)...

Qui parlo di file, ma il vettore con gli interi contenuti nel file te lo devi caricare in memoria... Inoltre questo permetterebbe di stimare anche il trasferimento a blocchi...

anzikè salvarsi tutti gli interi sul file non sarebbe meglio salvarsi i seed da utilizzare x generare i numeri casuali dei vari vettori????
se ad esempio deve ordinare vettori di 1000 elelementi, salvandosi i 1000 interi sul file puù usarli come semi e generare questi 1000 vettori.....
così deve leggere solo 1000 numeri dall'hdd anzikè 1000000... e penso sia meglio renderlo il più indipendente possibile dall'hdd visto ke nn deve misurare le sue prestazioni ma quelle del processore

cionci
04-05-2005, 09:24
Certo...ma se uno dovesse scegliersi i numeri ad hoc...

Comuqnue il tempo di caricamento dall'HD sarebbe al di fuori del benchmark...infatti ho scritto che una volta caricati tutti i numeri in un vettore non ci dovrebbe più accedere all'HD...

cionci
04-05-2005, 09:28
ho dimenticato di specificare che l'algoritmo (sia il mio che quello del prof) non deve trovare la posizione d'inizio e fine del sottovettore cercato, ma solamente il peso; nell'esempio precedente il risultato doveva essere 17.
Ho appena finito...con un solo ciclo di clock e trova anche l'inizio e la fine del sottovettore...

^TiGeRShArK^
04-05-2005, 10:18
Ho appena finito...con un solo ciclo di clock e trova anche l'inizio e la fine del sottovettore...
con un solo ciclo di clock???? MITIIIIIICOOOO! :sofico::asd::asd::asd:

cionci
04-05-2005, 10:20
con un solo ciclo di clock???? MITIIIIIICOOOO! :sofico::asd::asd::asd:
For... :D :D :D

3nigma666
04-05-2005, 12:10
kla storia del sottovettore massimo la conoscevo gia,ho scelto solo il quicksort a posto dell'algoritmo da te descritto,in quanto lo ritenevo piu efficace x studiarne l effettiva capacita di calcolo di un processore,in quanto è semplice dare in pasto al processore un algoritmo di costo computazionale lineare...In questa maniera non si testa a mio avviso l effettiva efficienza del processore,bisogna dare in "pasto" alla cpu algoritmi un attimino piu sostanzioni come costo computazionale,la piu o meno efficienza serve "solo" per ottenere piu velocemente il risultato.Per questo motivo ho scelto il QuickSort ke ha complessita a mio avviso molto piu interessante T(n) = O(nlogn) piuttosto ke il tuo ke per dare risultati simili puo avere slo costo di T(n) = O(n) quindi lineare. Potevio prendere altri algoritmi tipo le otimizzazioni del quickSort con Insertion SOrt o con Heap Sort,ma incominciavano ad avere un costo com,putazionale troppo basso e quindi non piu interessante.Decisamente piu efficace sarebbe lo stdio dei frattali ,ma ahime ancora non ho la teoria sufficiente alle spalle per poter affrontare tale argomento..so ke purtroppo è limitato il mio benchmark in quanto non si puo efficaciemente studiare la velocita con la uqale si interfaccia con la cache e ke quantita di dati puo trasportare,devo ovviamente migliorerare questo aspetto. Cionci corregimi se sbaglio,potrei osservare la velocita di "dialogo" con la cache dichiarando le variabili con il tipo: register int. Pero sapevo ke spesso il compilatore automaticamente se non riesce ad allocare in cache alloca in ram,senza comunicare niente all'utente!
Per quanto riguarda l'algoritmo del tuo professore,correggimi se sbaglio ma penso ke abbia fatto un cosa del genere:

una funzione piu generale ke chaimeremo
PESO MAX: non fa altro ke richiamare dentro ad un unico ciclo for la funzione CALCOLA_PESO
CALCOLA_PESO: somma il valore i-esimo del vettore a somma temporanea dei valori contigui presenti,e se la somma è maggiore di quella massima precedentemente trovata (il caso base ovviamente è somma = 0)
la sostituisce e ricorsivamente richiama se stesso fino fine vettore.
Inoltre calcola peso ritonora il valore dell'indice i uguale all'inizio del vettore contiguo sucecsisvo a quello appena analizzato.

cosi basta 1 solo ciclo for,certo mancano alcune chirificazioni e controlli degli indici ma credo ke l idea di base sia corretta no?? se puoi postaci lo pseudo codice del tuo prof

cionci
04-05-2005, 12:18
E quello dentro a CALCOLA_PESO che ciclo è ?!?!!? E' un ciclo anche quello...

Riguardo al register...register può tranquillamente non essere rispettato dal compilatore... In ogni caso register significa che il compilatore tenta di memroizzare la variabile all'interno dei registri del processore, quindi in teoria con la cache non ha niente a che vedere...

71104
04-05-2005, 13:46
Ho appena finito...con un solo ciclo di clock e trova anche l'inizio e la fine del sottovettore...
ehm... :sofico:
ma scusa quanti elementi ci hai messo nel vettore? quanto ci mette la tua soluzione con 10 milioni di elementi? mi posti il codice che hai scritto?
NON E' CHE NON CI CREDO, EH!!! (nnnnuuuuuuuuuuuuuuuuuu... :D), è solo che sai, come dire, dal momento che un solo ciclo di clock non basta manco a fare una comparazione... :sofico:

PS: non ti do un bel niente se riesci a realizzarmelo tu l'algoritmo; casomai al mio professore, non a te! ;) :p

71104
04-05-2005, 13:46
For... :D :D :D
ma LOL :D l'ho letto ora :D :D :D
e che ragionamento hai fatto?
(non mi venire a dire che hai copiato un algoritmo trovato su Google...)

71104
04-05-2005, 13:49
Per quanto riguarda l'algoritmo del tuo professore,correggimi se sbaglio ma penso ke abbia fatto un cosa del genere:

una funzione piu generale ke chaimeremo
PESO MAX: non fa altro ke richiamare dentro ad un unico ciclo for la funzione CALCOLA_PESO
CALCOLA_PESO: somma il valore i-esimo del vettore a somma temporanea dei valori contigui presenti,e se la somma è maggiore di quella massima precedentemente trovata (il caso base ovviamente è somma = 0)
la sostituisce e ricorsivamente richiama se stesso fino fine vettore.
Inoltre calcola peso ritonora il valore dell'indice i uguale all'inizio del vettore contiguo sucecsisvo a quello appena analizzato.

cosi basta 1 solo ciclo for,certo mancano alcune chirificazioni e controlli degli indici ma credo ke l idea di base sia corretta no?? se puoi postaci lo pseudo codice del tuo prof

assolutamente NO!!! l'algoritmo del prof. non era ricorsivo!!! (gli algoritmi ricorsivi ci mettono troppo tempo)
era iterativo purissimo!!! :eek:
cmq lo pseudocodice non te lo posto finché cionci non posta il suo :D

EDIT: aggiungo anche che l'algoritmo del prof., supponendo di avere a disposizione una funzioncina Max che calcola il massimo tra due valori, era lungo esattamente 6 righe!!!!!! :eek:
(cmq non pensate chissacchè, l'algoritmo non l'ha inventato lui (figuriamoci :D) l'ha letto su un libro; originariamente il problema era un problema di grafica)

71104
04-05-2005, 13:54
aggiungo anche che l'algoritmo del prof., supponendo di avere a disposizione una funzioncina Max che calcola il massimo tra due valori, era lungo esattamente 6 righe!!!!!! :eek:
4 se escludiamo l'inizializzazione delle variabili :D

cionci
04-05-2005, 14:02
ma LOL :D l'ho letto ora :D :D :D
e che ragionamento hai fatto?
(non mi venire a dire che hai copiato un algoritmo trovato su Google...)
Per ora è molto lento.... Stavo lavorando ad una versione nettamente più veloce (O(N)), ma devo gestire alcuni casi particolari in cui non mi torna...

Eccolo qui:

for(i=1; ; ++i)
{
if(i > end)
{
if(somma > max)
{
max = somma;
start_max = start;
end_max = end;
}

somma = 0;
if(++end == N)
end = ++start;

i = start;
if(i == N)
break;
}
somma += v[i];
}

71104
04-05-2005, 14:52
non vale, hai barato!!! :D
che bas****o!!!! :D
non puoi modificare il contatore i all'interno del ciclo for!!! :D
cmq funziona, però ti faccio presente che quell'algoritmo è pessimo, cioè bastano 2000 elementi per metterlo in difficoltà (8 secondi...)
la seconda versione del mio algoritmo veniva messa in difficoltà sui 100000 (tra i 10 e i 20 secondi, molto variabile), e l'ultima versione che ho fatto ha un costo di (N^2)/4 (inizia ad avere difficoltà sui 40000, 4 secondi se ricordo bene).
inoltre ho capito come funziona la versione del prof., ma realizzarla è molto difficile :mbe:

cionci
04-05-2005, 14:56
Certo...lo so che è pessimo ;)

71104
05-05-2005, 22:04
up!
allora cionci, la tua nuova versione?
ti arrendi e posto la soluzione di 6 righe? :D

VICIUS
05-05-2005, 22:52
Strano che non si sia ancora fatto vivo a2000 con una versione in vb da 3 righe con velocita sconvolgenti :D

ciao ;)

cionci
06-05-2005, 02:04
up!
allora cionci, la tua nuova versione?
ti arrendi e posto la soluzione di 6 righe? :D
Non ci ho più lavorato...comunque vai pure...

71104
06-05-2005, 08:14
RULLO DI TAMBURI
(ttrrrrrrrrrr...)

int i;
int max = 0, tail = 0;
for (i = 0; i < N; i++) {
max = Max(max, v[i] + tail);
tail = Max(0, v[i] + tail);
}

CIASSSSSSS!!! (onomatopea dei piatti alla fine del rullo di tamburi :D)

ovviamente:
- N è il numero di elementi
- v è il vettore (di N elementi)
- max alla fine contiene il risultato
- Max è una funzioncina che restituisce il massimo di due valori interi

stima dei tempi di calcolo: N!!! :eek:
(e ovviamente funziona... :mc: )

DanieleC88
07-05-2005, 14:58
Strano che non si sia ancora fatto vivo a2000 con una versione in vb da 3 righe con velocita sconvolgenti :D
:rotfl:
Già... Non ricordo in che discussione aveva postato quel codice fantastico di tre righe... :D

71104
07-05-2005, 23:52
ma chi è sto a2000? mica lo conosco... io sapevo di repne scasb, che ottimizzava in modo maniacale fino all'estremo e "aiutava" il compilatore scrivendo codice pressoché illeggibile, ma a2000 non l'ho mai visto

DanieleC88
08-05-2005, 07:23
Tempo fa l'avevo trovato in alcune discussioni, ma ora sembra essere scomparso.

cionci
09-05-2005, 01:28
ma chi è sto a2000? mica lo conosco... io sapevo di repne scasb, che ottimizzava in modo maniacale fino all'estremo e "aiutava" il compilatore scrivendo codice pressoché illeggibile, ma a2000 non l'ho mai visto
Ci sono stati alcuni thread davvero mitici con a2000... E' un integralista del Fortran con una preparazione matematica notevole...

71104
09-05-2005, 11:12
Ci sono stati alcuni thread davvero mitici con a2000... E' un integralista del Fortran con una preparazione matematica notevole...
O_o peccato non ci sia più, mi incuriosisce...

DanieleC88
09-05-2005, 12:09
Ci sono stati alcuni thread davvero mitici con a2000... E' un integralista del Fortran con una preparazione matematica notevole...
Qualcuno mi parla un po' di Fortran? Non ho mai visto niente scritto in Fortran e non so che linguaggio è.

Preparazione matematica notevole... hmm, il mio opposto, allora. :D

repne scasb
09-05-2005, 18:44
(e ovviamente funziona... )

E' possibile che non abbia capito correttamente il problema, ma mi sembra di poter dire che l'algoritmo suggerito dal tuo professore non sia in grado di funzionare correttamente: Ossia, sia V[...] un vettore costituito dalle componenti: V[-1,-2,-3], il sottovettore con maggior peso "dovrebbe" essere -1, mentre l'algoritmo che hai mostrato "ritorna" come risultato 0.

Potrei pero' aver capito male il significato della funzione Max().

71104
09-05-2005, 19:27
E' possibile che non abbia capito correttamente il problema, ma mi sembra di poter dire che l'algoritmo suggerito dal tuo professore non sia in grado di funzionare correttamente: Ossia, sia V[...] un vettore costituito dalle componenti: V[-1,-2,-3], il sottovettore con maggior peso "dovrebbe" essere -1, mentre l'algoritmo che hai mostrato "ritorna" come risultato 0.

Potrei pero' aver capito male il significato della funzione Max().
LOOOOL :D nono, hai proprio ragione! Max è semplicemente una funzione che ritorna il massimo dei due interi che gli sono stati passati (penso che tu abbia capito bene)
l'algoritmo con quel vettore non funziona :D
questa gliela voglio proprio dire al prof. :D
cmq secondo me il problema è semplicemente che a un certo punto Max viene utilizzata col valore 0, e quindi certe volte una variabile assume il valore 0 quando invece dovrebbe assumere l'altro valore (quello negativo); secondo me il problema si può correggere, e cmq penso che non si presenti affatto quando nel vettore è presente almeno un numero positivo.

cionci
09-05-2005, 19:35
Come si potrebbe risolvere ? Magari confrontando con INT_MIN ?

71104
09-05-2005, 19:36
Il problema è di facile risoluzione...basta inizializzare a INT_MIN...
esattamente quello che pensavo io; ora provo :)

cionci
09-05-2005, 19:38
esattamente quello che pensavo io; ora provo :)
Non basta...perchè se il primo è un intero negativo si va in underflow...

Nemmeno in confronto con INT_MIN ha senso...

71104
09-05-2005, 19:42
non funziona, mi restituisce INT_MIN... :(

71104
09-05-2005, 19:43
non funziona, mi restituisce INT_MIN... :(
giustamente! quello che bisogna fare è inizializzare al massimo numero negativo presente nel vettore! ti torna?
solo che così i for diventano due e il tempo di calcolo è O(2N)

71104
09-05-2005, 19:47
giustamente! quello che bisogna fare è inizializzare al massimo numero negativo presente nel vettore! ti torna?
solo che così i for diventano due e il tempo di calcolo è O(2N)
no, perché poi non funziona se nel vettore ci aggiungo un numero positivo... boh, tra tutti i metodi che ho provato (metodo del prof., metodi miei e metodo "cionci" :)) l'unico che sembra funzionare sempre è il metodo più scemo, lo posto qui di seguito:

int f(int x[], int n) {
int p = x[0];
int i, j;
for (i = 0; i < n; i++) {
for (j = 0; j <= i; j++) {
int q = 0, k;
for (k = j; k <= i; k++) {
q += x[k];
}
if (q > p) {
p = q;
}
}
}
return p;
}