|
|||||||
|
|
|
![]() |
|
|
Strumenti |
|
|
#21 | |
|
Senior Member
Iscritto dal: Jul 2006
Messaggi: 484
|
Quote:
Se qualcuno può postarmi qualche guida e o suggerimento per utilizzare librerie gliene sarei grato ![]() Attualmente non sono pratico nella creazione di una libreria, menche meno nella creazione di una libreria altamente ottimizzata per il calcolo del seno e coseno, non conosco così affondo l'assembly da poter sfruttare a basso livello le istruzioni processore ed ottenere un risultato migliore di quanto non faccia la funzione standard. Ho provato ad utilizzare qualche altra funzione trovata in rete, dei metodi di approssimazione del seno e del coseno, fra quei pochi che sono riusciti a far funzionare risultavano tutti più lenti. Ultima modifica di Rossi88 : 23-07-2009 alle 19:39. |
|
|
|
|
|
|
#22 | |
|
Senior Member
Iscritto dal: Jul 2006
Messaggi: 484
|
Quote:
Per l'unroll ho provato a fare un unroll di passo 2 per un'altra funzione che anch'essa richiamata svariate milioni di volte ma non prevede la necessità di utilizzare seno e coseno e quindi risulta ben più veloce ma anche in questo caso non ho riscontrato miglioramenti. Nel corpo di questa funzione vi sono vari prodotti e somme. Ho provato a fare un unroll di 64 semplicemente per fare una cosa più estrema e verificare se c'erano dei miglioramenti, non pensando ad eventuali riscontri negativi per quanto riguarda la cache. Devo cercare di utilizzare quelle librerie che mi hai consigliato, ma sono un po' in alto mare, non capisco perchè non ci sia una guida facile facile su come utilizzare delle librerie non fornite direttamente con l'IDE Ultima modifica di Rossi88 : 23-07-2009 alle 19:33. |
|
|
|
|
|
|
#23 | |
|
Senior Member
Iscritto dal: Nov 2002
Messaggi: 6287
|
Quote:
Codice:
cl driver.c -Ic:/acml4.3.0/win64_mp/include c:/acml4.3.0/win64_mp/lib/libacml_mp_dll.lib driver.c c1: fatal error C1083: Cannot open source file: 'driver.c': No such file or directory http://biowulf.nih.gov/doc/acml/Link...2fWindows.html Il file driver.c magari non va sostituito con il nome del tuo sorgente? Quello è solo un esempio presumo..Riguardo il restrict, se non hai miglioramenti vuol dire che il compilatore non fa ottimizzazioni su quel loop, oppure che le fa ed è riuscito a capire che tale puntatore ha un utilizzo ristretto, quindi aggiungendola tu non cambia nulla. Io comunque la lascerei, non si sa mai.. Ultima modifica di Unrue : 23-07-2009 alle 22:04. |
|
|
|
|
|
|
#24 | |
|
Senior Member
Iscritto dal: Feb 2006
Messaggi: 1304
|
Quote:
Quindi basta riportare l'angolo in questo intervallo (una divisione) e regolare il segno di conseguenza. Tutto sta a decidere la risoluzione dei valori della tabella, ma come dice _Claudio in 5-6 mb ci stanno milioni di valori... difficile notare la differenza in precisione. Mentre quella in velocità sarebbe decisamente evidente
|
|
|
|
|
|
|
#25 | |
|
Senior Member
Iscritto dal: Jul 2006
Messaggi: 484
|
Quote:
comunque ho provato a quindi a mettere tutti i file del mio programma e mettere i percorsi corretti, non da alcun errore del tipo non riesco a trovare o aprire quel file o quella libreria, ma da lo stesso identico errore che mi da compilando direttamente dall'IDE ossia unresolved external linker, eppure ho provato sia con le librerie nella cartella win64 che in quela win64_mp, ho provato persino a mettere tutte le librerie ma mi da errore dicendo che alcune librerie vanno in conflitto chissà come mai Comunque ho creato una stupida libreria, una libreria che come unica funzione ha questa Codice:
int SempliceSomma(int a,int b); poi ho creato un semplice programma Codice:
#include <stdio.h>
#include <windows.h>
#include <IntestazioneLibreria.h>
int main()
{
printf("Prova Compilazione\n");
printf("%d \n",SempliceSomma(3,6));
system("PAUSE");
return 0;
}
Poi ho fatto gli stessi identici passi nel programma vero e proprio ma l'unresolved link rimane riporto l'errore esatto comunque: Codice:
error LNK2019: unresolved external symbol _fastsincos referenced in function _derivsU Ultima modifica di Rossi88 : 24-07-2009 alle 18:48. |
|
|
|
|
|
|
#26 | |
|
Senior Member
Iscritto dal: Jul 2006
Messaggi: 484
|
Quote:
Codice:
int i;
double *ValoriTabellati;
ValoriTabellati=(double *)malloc(sizeof(double)*40000001);
for (i=0;i<=40000000;i++)
{
ValoriTabellati[i]=sin(2*3.14*i/40000000);
}
con fmod dovrei ottenere il resto della divisione fra esp e 2*pi, poi dovrei ottenere l'indice corrispondente all'angolo ed arrotondarlo con floor, e poi accedere a quell'indice. Implemento il tutto e faccio sapere i risultati |
|
|
|
|
|
|
#27 |
|
Senior Member
Iscritto dal: Jul 2006
Messaggi: 484
|
Ho implementato il codice ed ho fatto qualche prova, innanzitutto riporto il codice:
Codice:
int i;
ValoriTabellatiCos=(double *)malloc(sizeof(double)*(NTABELLATI+1));
ValoriTabellatiSin=(double *)malloc(sizeof(double)*(NTABELLATI+1));
for (i=0;i<=NTABELLATI;i++)
{
ValoriTabellatiCos[i]=cos(DUEPERPISUNTABELLATI*i);
ValoriTabellatiSin[i]=sin(DUEPERPISUNTABELLATI*i);
}
Codice:
q1=K*sin(esp); q2=K*cos(esp); Codice:
if (esp==0)
{
q1=0;
q2=K;
}
else
{
ValoreAssoluto=fabs(esp);
IndiceRicerca=(int) floor((fmod(ValoreAssoluto,DUEPERPI)*NTABELLATISUDUEPERPI)+0.5);
q1=K*esp/ValoreAssoluto*ValoriTabellatiSin[IndiceRicerca];
q2=K*ValoriTabellatiCos[IndiceRicerca];
}
Senza Tabella 1.04 Con Tabella da 700000 valori 1.02 Con Tabella da 400000 valori 0.52 Con Tabella da 40000 valori 0.37 Con Tabella da 4000 valori 0.39 Quindi al di sotto di 40000 valori il tempo è praticamente identivo (il tempo lo rilevo a mano e poi avevo decine di pagine internet aperte e visual studio aperto quindi qualche secondo di differenza ci può stare comunque anche per un 4000 valori l'errore massimo relativo è dell'ordine dello 0.01% quindi del tutto trascurabile (farò alter prove per verificare tempi ed accuratezza dei risultati). Nel caso questa dovesse risultare un'ottimo approccio penso di utilizzare una tabella da 40000 valori che mi da un errore relativo di due ordini di grandezza inferiore. Se qualcuno ha suggerimenti per migliorare quella porzione di codice, in particolare per eliminare l'if che dovrebbe far perdere un bel po' di tempo o per ovviare a qualche chiamata a funzioni fmod e floor non esiti a postare Qualsiasi commento e soluzione è ben accetta. (Ovviamente i ringraziamenti a tutti coloro che stanno cercando e che cercheranno di aiutarmi sono scontati Ultima modifica di Rossi88 : 24-07-2009 alle 22:06. |
|
|
|
|
|
#28 |
|
Senior Member
Iscritto dal: Jul 2006
Messaggi: 484
|
Comunque inizio ad avere dei forti dubbi sull'analizzatore di performace di Visual Studio 2010 beta 1, perchè il tempo per creare le due tabelle da 40.000.000 valori quindi 80.000.000 chiamate alle funzioni seno e coseno (e altrettante divisioni) risulta essere pressochè nullo 1-2 secondi
Ultima modifica di Rossi88 : 24-07-2009 alle 22:17. |
|
|
|
|
|
#29 |
|
Senior Member
Iscritto dal: Feb 2006
Messaggi: 1304
|
Vedi che era più veloce
Cmq l'if lo puoi proprio togliere, dato che 0.0/0.0 coi float è definito come #inf e cos0 e' 1 (valore che puoi includere nella tabella). Potresti anche togliere floor() che dato il minimo intervallo di angolo tra il valore approssimato per difetto e per eccesso non porta ad alcuna imprecisione. Per il resto se vuoi misurare il tempo è meglio che usi GetQueryPerformanceCounter & co su windows che dà la massima precisione... Inoltre dovresti considerare di ridurre le chiamate a funzione, che hanno si un peso irrisorio ma quando n fai 3.700.000 iniziano a farsi sentire come overhead ![]() Prova a mettere quella che è derivsU all'interno di un ciclo while di una funzione più ampia, per esempio. |
|
|
|
|
|
#30 | |
|
Senior Member
Iscritto dal: Jul 2006
Messaggi: 484
|
Quote:
per quanto riguarda 0/0 si evvero da #inf, però poi quel valore lo utilizzo nelle successive due istruzioni di codice Codice:
dydx[i]-=q1*y[j]+q2*y[j+n]; dydx[i+n]+=q2*y[j]-q1*y[j+n]; Utilizzerò GetQueryPerformanceCounter come mi hai suggerito per meglio misurare i tempi di esecuzione |
|
|
|
|
|
|
#31 |
|
Senior Member
Iscritto dal: Feb 2006
Messaggi: 1304
|
Uhm già allora l'if serve... comunque quanto pesa dipende dall'incidenza di casi true sul totale: cioè se esp è 0 pochissime volte il valutare l'if potrebbe diventare più pesante di fare il calcolo e basta.
Comunque non saprei come renderlo più leggero, probabilmente l'if non pesa poi tanto. Cmq i puntatori a funzione pesano molto di più delle chiamate a funzione normali, secondo me potresti farci qualcosa. Certo, perderesti tantissimo in mantenibilità e gestibilità... |
|
|
|
|
|
#32 |
|
Senior Member
Iscritto dal: Nov 2002
Messaggi: 6287
|
|
|
|
|
|
|
#33 | |
|
Senior Member
Iscritto dal: Jul 2006
Messaggi: 484
|
Quote:
L'idea di utilizzare delle tabelle con i valori già precalcolati è interessante, però riuscire ad utilizzare delle librerie specificatamente pensate per sfruttare le nuove potenzialità dei processori, poter utilizzare in maniera più veloce i vettori mi piaceva ancor di più. |
|
|
|
|
|
|
#34 |
|
Senior Member
Iscritto dal: Nov 2002
Messaggi: 6287
|
Sto usando vari compilatori tra i quali Intel, PGI e GCC. Ma devi per forza usare Visual Studio? Prova con Gcc per Windows a vedere se ti funziona.
|
|
|
|
|
|
#35 |
|
Senior Member
Iscritto dal: Jul 2006
Messaggi: 484
|
A distanza di tempo ed usando Visual studio 2010 beta 2 ho riprovato ad utilizzare le librerie ACML e (probabilmente sbagliavo qualcosa oppure Visual Studio 2010 beta 1 aveva qualche problema) la procedura per chi volesse utilizzare tali librerie con Visual studio è la seguente:
1) installare ACML 2) nel programma inserire gli header necessari, ad esempio Codice:
#include <acml.h> Codice:
Project->NomeProgetto Properties->Configuration Properties->VC++ Directories->Include Directories 4) indicare i file .lib necessari, ad esempio Codice:
Project->NomeProgetto Properties->Configuration Properties->VC++ Directories->Linker->Input->Additional Dependencies 5) copiare tutti i file .dll nella cartella di lavoro del progetto (Testato con Windows 7) |
|
|
|
|
|
#36 |
|
Senior Member
Iscritto dal: Nov 2002
Messaggi: 6287
|
Ciao,
visto che lavori su processore Intel, forse sono più indicate le MKL ( Math Kernel Library), sviluppate da Intel stessa. A suo tempo ti indicai le ACML in quanto le MKL ancora non le conoscevo Inoltre ti consiglio anche di utilizzare il compilatore Intel ( icc), versione free. In genere è più performante di gcc, sopratutto su architetture Intel. Ultima modifica di Unrue : 05-12-2009 alle 16:12. |
|
|
|
|
|
#37 |
|
Senior Member
Iscritto dal: Dec 2003
Città: Piano di Sorrento (NA)
Messaggi: 924
|
Dico una stupidaggine: hai provato ad utilizzare funzioni inline?
__________________
Affari conclusi perfettamente con: falcao3, maxmax80 |
|
|
|
|
|
#38 |
|
Senior Member
Iscritto dal: Jul 2006
Messaggi: 484
|
@HyperText
No non ho provato ad usare funzioni inline, devo approfondire dato che se definisco la funzione con la parola chiave __inline il compilatore mi da un unresolved link. Utilizzando ACML sono riuscito ad ottenere oltre il 50% di riduzione dei tempi di calcolo (rispetto a prima dell'utilizzo di ACML, quindi complessivamente un codice 30 volte più veloce @Unrue Sai per caso di qualche buona guida per le funzioni BLAS? Finora sono riuscito a trovare tutte le funzioni che mi servivano tranne una, il prodotto elemento per elemento (element-wise) fra due vettori (o matrici) tu conosci quale funzione devo usare? (ho letto che si parla anche di Hadamard product, ho trovato anche una funzione ma non c'è in ACML) Attualmente faccio il prodotto elemento per elemento tramite il classico ciclo for e ciò mi comporta oltre il 15% di tempo, se potessi farlo tramite BLAS otterrei una ulteriore riduzione di tempo Comunque ho letto che le GPU consentono di effettuare il calcolo del seno e del coseno con 1 ciclo Per quanto riguarda MKL e il compilatore Intel non sono gratuiti per Windows mi sembra, anche se in MKL si ha la possibilità di fare operazioni direttamente con i numeri complessi, che mi eviterebbe di passare per le funzioni sin e cos, quindi potrebbe essere molto interessante. |
|
|
|
|
|
#39 | |||||
|
Senior Member
Iscritto dal: Nov 2002
Messaggi: 6287
|
Quote:
Quote:
http://www.netlib.org/blas/ Quote:
Quote:
Quote:
http://software.intel.com/en-us/arti...ware-download/ PS: Hai lasciato l'unroll dei loop come ti avevo suggerito a suo tempo? Considera anche che non puoi ottimizzare all'infinito, arrivi ad un certo punto che più di lì non vai. 30 volte più veloce mi sembra già più che ottimo. Ultima modifica di Unrue : 06-12-2009 alle 12:02. |
|||||
|
|
|
|
|
#40 |
|
Senior Member
Iscritto dal: May 2000
Messaggi: 1459
|
in genere buona pratica è eliminare tutti i rapporti, calcolare prima il reciproco e poi fare il prodotto col divisore.
double rec = 1/x; double z=y*x; invece di double z = y/x; ora non ricordo bene l'assembly che viene generato nei due casi, ma se non mi sbaglio il primo caso è abbastanza + veloce (mi pare di ricordare che per il calcolo del reciproco c'è un'istruzione ad hoc o qualcosa del genere) bye |
|
|
|
|
| Strumenti | |
|
|
Tutti gli orari sono GMT +1. Ora sono le: 13:07.













Quello è solo un esempio presumo..
comunque ho provato a quindi a mettere tutti i file del mio programma e mettere i percorsi corretti, non da alcun errore del tipo non riesco a trovare o aprire quel file o quella libreria, ma da lo stesso identico errore che mi da compilando direttamente dall'IDE ossia unresolved external linker, eppure ho provato sia con le librerie nella cartella win64 che in quela win64_mp, ho provato persino a mettere tutte le librerie ma mi da errore dicendo che alcune librerie vanno in conflitto chissà come mai









