|
|||||||
|
|
|
![]() |
|
|
Strumenti |
|
|
#1 | |
|
Senior Member
Iscritto dal: Feb 2001
Città: Firenze
Messaggi: 361
|
[C/C++] Intel Centrino batte AMD64 con gli array
Ciao. Chiedo gentilmente opinione e consiglio a tutti.
Questo programma di esempio gira con tempi strani e, soprattutto porta alla vittoria di un centrino 1.6MHz (Dothan) contro un AMD64-3000+(Winchester). Vi inviterei a provare. Il codice lo trovate in fondo. Riassunto veloce: - array 13x13, ma la dimensione non è vincolante. - le matrici sono int e unsigned char - vengono inizializzate 100milioni di volte Le inizializzazioni sono di due tipi: - una percorre la matrice da sinistra a destra - l'altra dall'alto verso il basso Compilo su un Centrino 1.6 con gcc 3.3.5 ed opzioni -03 -g0 e si ottengono i seguenti tempi: Quote:
Comincia non tornare nella scarsa o nessuna differenza tra l'uso di int e uchar, che dovrebbero essere indirizzate a 16 e 8 bit rispettivamente. Non mi torna per niente che questo programmino giri più lento su un AMD64-3000+. Ditemi voi cosa ne pensate. Grazie e ciao! Andrea Codice: Codice:
#include <iostream>
#include <cstdlib>
#define K 12
#define BOUND 100000000
using namespace std;
int main(int argc, char *argv[])
{
unsigned char matrixC [K+1][K+1];
int matrixI [K+1][K+1];
unsigned long startTime;
unsigned long finishTime;
/*
In tutte le matrici non si fa altro che assegnare un valore
fissato per ogni elemento un numero di volte pari a BOUND
*/
cout << "\n\nStarting up-down mode INT..." << endl;
startTime = time(0);
for (int M = 0; M < BOUND; M++)
for (int j = 0; j <= K; j++)
for (int i = 0; i <=K; i++)
matrixI[i][j] = 1;
finishTime = time(0);
cout << "Elapsed : " << finishTime-startTime << " secs." << endl;
cout << "\n\nStarting up-down mode UCHAR..." << endl;
startTime = time(0);
for (int M = 0; M < BOUND; M++)
for (int j = 0; j <= K; j++)
for (int i = 0; i <=K; i++)
matrixC[i][j] = 2;
finishTime = time(0);
cout << "Elapsed : " << finishTime-startTime << " secs." << endl;
cout << "\nStarting left-right mode INT..." << endl;
startTime = time(0);
for (int M = 0; M < BOUND; M++)
for (int i = 0; i <= K; i++)
for (int j = 0; j <=K; j++)
matrixI[i][j] = 3;
finishTime = time(0);
cout << "Elapsed : " << finishTime-startTime << " secs." << endl;
cout << "\nStarting left-right mode UCHAR..." << endl;
startTime = time(0);
for (int M = 0; M < BOUND; M++)
for (int i = 0; i <= K; i++)
for (int j = 0; j <=K; j++)
matrixC[i][j] = 4;
finishTime = time(0);
cout << "Elapsed : " << finishTime-startTime << " secs." << endl;
return EXIT_SUCCESS;
}
__________________
Utenti Utenti Ultima modifica di andreaM : 12-09-2005 alle 17:54. |
|
|
|
|
|
|
#2 |
|
Senior Member
Iscritto dal: Jun 2002
Città:
Provincia De VaRéSe ~ § ~ Lat.: 45° 51' 7" N Long.: 8° 50' 21" E ~§~ Magica Inter ~ § ~ Detto: A Chi Più Amiamo Meno Dire Sappiamo ~ § ~ ~ § ~ Hobby: Divertimento allo Stato Puro ~ § ~ ~ § ~ You Must Go Out ~ § ~
Messaggi: 8897
|
devi provare a compilare ottimizzando il codice per ogni piattaforma, li capisci realmente il limite della cpu.
~§~ Sempre E Solo Lei ~§~
__________________
Meglio essere protagonisti della propria tragedia che spettatori della propria vita
Si dovrebbe pensare più a far bene che a stare bene: e così si finirebbe anche a star meglio. Non preoccuparti solo di essere migliore dei tuoi contemporanei o dei tuoi predecessori.Cerca solo di essere migliore di te stesso |
|
|
|
|
|
#3 | |
|
Senior Member
Iscritto dal: Feb 2001
Città: Firenze
Messaggi: 361
|
Quote:
Su AMD64 ho provato a dare delle opzioni a gcc mirate proprio a questo, del tipo: -march , -mcpu , -m32 o m64 (una alla volta) per legare l'eseguibile all'architettura sottostante eppure non è cambiato proprio nulla. Un idea?
__________________
Utenti Utenti |
|
|
|
|
|
|
#4 |
|
Senior Member
Iscritto dal: Jun 2002
Città:
Provincia De VaRéSe ~ § ~ Lat.: 45° 51' 7" N Long.: 8° 50' 21" E ~§~ Magica Inter ~ § ~ Detto: A Chi Più Amiamo Meno Dire Sappiamo ~ § ~ ~ § ~ Hobby: Divertimento allo Stato Puro ~ § ~ ~ § ~ You Must Go Out ~ § ~
Messaggi: 8897
|
per intel c'è il compilatore sui volendo ma ti costa un botto, poi prova a fare ottimizzione migliore che se non erro è -o3
~§~ Sempre E Solo Lei ~§~
__________________
Meglio essere protagonisti della propria tragedia che spettatori della propria vita
Si dovrebbe pensare più a far bene che a stare bene: e così si finirebbe anche a star meglio. Non preoccuparti solo di essere migliore dei tuoi contemporanei o dei tuoi predecessori.Cerca solo di essere migliore di te stesso |
|
|
|
|
|
#5 | |
|
Senior Member
Iscritto dal: Feb 2001
Città: Firenze
Messaggi: 361
|
Quote:
Io non sono sicuro che si tratti di un problema di compilazione non ottimizata. Infatti ci sono altri tipi di programmi che ho realizzato, meno sensibili all'indirizzamento e più esosi di clock: lì le cose cambiano, eppure la piattaforma è la stessa... Guarda è un bel rompicapo. Ciao.
__________________
Utenti Utenti |
|
|
|
|
|
|
#6 |
|
Senior Member
Iscritto dal: Apr 2000
Città: Vicino a Montecatini(Pistoia) Moto:Kawasaki Ninja ZX-9R Scudetti: 29
Messaggi: 53971
|
Intanto le matrici sono 13x13
E' possibilissimo che il P-M si più veloce dell'Athlon 64...non ci vedo niente di strano... L'alu del Pentium 3 è sempre stata molto efficiente... Il compilatore probabilmente alloca i char allineandoli ai 32 bit...di conseguenza la matrice di char occupa la stessa dimensione di una matrice di int... Questo perchè non è così agevole per le CPU moderne accedere solamente ad uno dei vari byte di una locazione a 32 bit... |
|
|
|
|
|
#7 | |||
|
Senior Member
Iscritto dal: Feb 2001
Città: Firenze
Messaggi: 361
|
Quote:
Quote:
Quote:
Grazie comunque per la risposta. Ciao.
__________________
Utenti Utenti |
|||
|
|
|
|
|
#8 |
|
Senior Member
Iscritto dal: Apr 2000
Città: Vicino a Montecatini(Pistoia) Moto:Kawasaki Ninja ZX-9R Scudetti: 29
Messaggi: 53971
|
Un int è già a 32 bit...non c'è bisogno di allinearlo...
Il P4 suppongo che vada più lento...anche se bisogna sempre vedere la frequenza... |
|
|
|
|
|
#9 | ||
|
Senior Member
Iscritto dal: Feb 2001
Città: Firenze
Messaggi: 361
|
Quote:
char a 8 bit int a 16 bit float a 32 bit double a 64 bit (per questo speravo quanto ti ho detto) ovviamente, però, i progettisti dei vari compilatori hanno fatto delle scelte diverse. Quote:
Pensavo piuttosto alla differenza di cache tra i due processori della prova: un Intel con core Banias ha 2MB di L2, mentre lo AMD Winchester ne ha 512KB. Non potrebbe essere? Ciao. Andrea
__________________
Utenti Utenti |
||
|
|
|
|
|
#10 | |
|
Senior Member
Iscritto dal: Apr 2000
Città: Vicino a Montecatini(Pistoia) Moto:Kawasaki Ninja ZX-9R Scudetti: 29
Messaggi: 53971
|
Quote:
Solitamente l'int è pari alla grandezza del registro della ALU... Questo programma sicuramente non risentirà della cache L2, visto che girerà sempre sulla L1... Gli accessi alla RAM quindi hanno una latenza molto bassa... Per ogni inizializzazione dovrai fare un solo accesso alla cache (suppongo solo uno visto che il vettore è allocato staticamente), ma dovrai fare una prodotto per calcolare l'indirizzo della linea (si fa con la ALU), un'altra somma per calcolare la posizione del dato nella linea (questa operazione si fa con la AGU), l'accesso alla cache, e poi per ogni for più interno: un incremento, un confronto ed una jump condizionata)... Sono 1 operazione AGU e 4 ALU per ogni accesso alla cache... Quindi suppongo che siano le 5 operazioni a dare un contributo superiore a quello dell'accesso alla cache... Ultima modifica di cionci : 09-09-2005 alle 22:09. |
|
|
|
|
|
|
#11 | |
|
Senior Member
Iscritto dal: Feb 2001
Città: Firenze
Messaggi: 361
|
Quote:
char 1 byte (come ANSI) int 4 byte float 4 byte (come ANSI) double 8 byte (come ANSI)
__________________
Utenti Utenti |
|
|
|
|
|
|
#12 | ||
|
Senior Member
Iscritto dal: Feb 2001
Città: Firenze
Messaggi: 361
|
Quote:
Quote:
Perfetto, Chiaro. Grazie.
__________________
Utenti Utenti |
||
|
|
|
|
|
#13 |
|
Senior Member
Iscritto dal: Jan 2002
Città: Germania
Messaggi: 26110
|
Le matrici sono piccole e stanno tutte nella cache L1, per cui può darsi che in questo caso la maggior efficienza dell'accesso alla cache dei Pentium-M faccia la differenza.
I char in questo dovrebbero occupare comunque 1 byte.
__________________
Per iniziare a programmare c'è solo Python con questo o quest'altro (più avanzato) libro @LinkedIn Non parlo in alcun modo a nome dell'azienda per la quale lavoro Ho poco tempo per frequentare il forum; eventualmente, contattatemi in PVT o nel mio sito. Fanboys |
|
|
|
|
|
#14 | |
|
Senior Member
Iscritto dal: Apr 2000
Città: Vicino a Montecatini(Pistoia) Moto:Kawasaki Ninja ZX-9R Scudetti: 29
Messaggi: 53971
|
Ora che ci penso con -O3 ci sta che faccia anche il loop unrolling...in questo caso ci sarebbero solo accessi alla L1...
Quote:
|
|
|
|
|
|
|
#15 |
|
Senior Member
Iscritto dal: Jan 2002
Città: Germania
Messaggi: 26110
|
Proprio perché i dati stanno tutti nella cache: una volta caricati, accedere a un byte o a un valore a 32 bit è indifferente per il processore.
__________________
Per iniziare a programmare c'è solo Python con questo o quest'altro (più avanzato) libro @LinkedIn Non parlo in alcun modo a nome dell'azienda per la quale lavoro Ho poco tempo per frequentare il forum; eventualmente, contattatemi in PVT o nel mio sito. Fanboys |
|
|
|
|
|
#16 | |
|
Senior Member
Iscritto dal: Apr 2000
Città: Vicino a Montecatini(Pistoia) Moto:Kawasaki Ninja ZX-9R Scudetti: 29
Messaggi: 53971
|
Quote:
|
|
|
|
|
|
|
#17 | |
|
Senior Member
Iscritto dal: Feb 2001
Città: Firenze
Messaggi: 361
|
Quote:
- questo tipo di programma porta la matrice in L1 e, ad ogni inizializzazione, la ALU calcola la posizione dell'elemento in cache. - per questo motivo usare char, short int o int non dovrebbe avere impatto sulle prestazione (anche se un po' invece succede). A patto che la matrice non diventi troppo grande e serva utilizzare anche la L2. - il Centrino va più veloce perchè ha una ALU più efficiente: su questo cdimauro concorda? Ciao.
__________________
Utenti Utenti |
|
|
|
|
|
|
#18 |
|
Senior Member
Iscritto dal: Apr 2000
Città: Vicino a Montecatini(Pistoia) Moto:Kawasaki Ninja ZX-9R Scudetti: 29
Messaggi: 53971
|
Secondo cdimauro la cache L1 del P-M è più efficiente...però sarei d'accordo su questo se con -O3 il compilatore facesse il loop unrolling...in tal caso il tutto si riduce ai soli accessi alla L1...
La differenza non c'è fra int e char perchè il protocollo di accesso alla L1 è identico sia che si voglia recuperare un int che un char... Ultima modifica di cionci : 12-09-2005 alle 13:13. |
|
|
|
|
|
#19 | |
|
Senior Member
Iscritto dal: Feb 2001
Città: Firenze
Messaggi: 361
|
Quote:
-funroll-loops -funroll-all-loops che però NON sono abilitate con nessuna opzione -Ox. Perciò le prestazioni misurate non beneficiano del loop unrolling.
__________________
Utenti Utenti |
|
|
|
|
|
|
#20 | |
|
Senior Member
Iscritto dal: Jan 2003
Città: Milano - Udine
Messaggi: 9418
|
Quote:
ma è cmq il doppio rispetto all'A64 |
|
|
|
|
|
| Strumenti | |
|
|
Tutti gli orari sono GMT +1. Ora sono le: 04:25.



















