|
|
|
![]() |
|
Strumenti |
![]() |
#1 |
Senior Member
Iscritto dal: Nov 2002
Messaggi: 6183
|
[C++] Strano problema di ottimizzazione
Ciao ragazzi, ho un problema apparentemente strano. Dunque, io ho una classe StandardBackprop, una ParNeuralNet ed un'altra Test.
La classe TrainingNet ha nel suo header un puntatore alla classe ParNeuralNet. Nella classe ParNeuralNet ho una funzione che è la causa del problema: Codice:
inline double ParNeuralNet::randomValue(double symmetric_range){ double zero_one_value=((double)rand()/((double)(RAND_MAX)+1.0)); double result=zero_one_value*(2.0*symmetric_range)-(symmetric_range); return result; } Codice:
TrainingNet->Par->randomValue(range_max) Il problema è che se compilo senza ottimizzazioni, tutto funziona liscio. Se invece metto l'ottimizzazione -O1, -O2, -O3, mi dice "undefined reference " a tale funzione. Se però la stessa funzione, invece di dichiararla inline, la definisco direttamente nell'header di ParNeuralNet, compila anche con ottimizzazioni ! In pratica, sembra che,a causa della doppia referenziazione per accedere alla funzione, non riesca a fare l'inline direttamente. Avete qualche spiegazione di ciò? Grazie. Ultima modifica di Unrue : 20-12-2007 alle 11:46. |
![]() |
![]() |
![]() |
#2 | |
Senior Member
Iscritto dal: Nov 2003
Messaggi: 980
|
Le funzioni inline le devi definire nell'header, devono essere disponibili subito al compilatore per essere espanse (o no, lo decide il compilatore)
Quote:
Ultima modifica di kk3z : 20-12-2007 alle 09:58. |
|
![]() |
![]() |
![]() |
#3 |
Senior Member
Iscritto dal: Nov 2002
Messaggi: 6183
|
Ok, ma ho altre funzioni inline nel codice, e non mi compare lo stesso errore. Solo sulla funzione sopra menzionata. Perchè questo ?
|
![]() |
![]() |
![]() |
#4 |
Senior Member
Iscritto dal: Nov 2003
Messaggi: 980
|
EDIT: modifico e mi crea un'altro post..
Ultima modifica di kk3z : 20-12-2007 alle 10:20. |
![]() |
![]() |
![]() |
#5 |
Senior Member
Iscritto dal: Nov 2003
Messaggi: 980
|
Ma tutte queste funzioni inline le chiami nello stesso modo (cioè dal puntatore di una classe che chiama una funziona di un'altra classe dal suo puntatore
![]() ![]() |
![]() |
![]() |
![]() |
#6 |
Senior Member
Iscritto dal: Nov 2002
Messaggi: 6183
|
|
![]() |
![]() |
![]() |
#7 | |
Senior Member
Iscritto dal: Oct 2002
Città: San Jose, California
Messaggi: 11794
|
Quote:
Ma soprattutto: perche' hai dichiarato quella funzione inline?
__________________
"We in the game industry are lucky enough to be able to create our visions" @ NVIDIA |
|
![]() |
![]() |
![]() |
#8 |
Senior Member
Iscritto dal: Nov 2002
Messaggi: 6183
|
|
![]() |
![]() |
![]() |
#9 | |
Senior Member
Iscritto dal: Oct 2002
Città: San Jose, California
Messaggi: 11794
|
Ok, perche' il comportamento del compilatore mi pare un po' strano.
Quote:
![]()
__________________
"We in the game industry are lucky enough to be able to create our visions" @ NVIDIA |
|
![]() |
![]() |
![]() |
#10 |
Senior Member
Iscritto dal: Apr 2000
Città: Roma
Messaggi: 15625
|
Unrue non è stato chiaro su dove ha messo l'implementazione, se è in un file sorgente allora il comportamento è corretto...
__________________
0: or %edi, %ecx; adc %eax, (%edx); popf; je 0b-22; pop %ebx; fadds 0x56(%ecx); lds 0x56(%ebx), %esp; mov %al, %al andeqs pc, r1, #147456; blpl 0xff8dd280; ldrgtb r4, [r6, #-472]; addgt r5, r8, r3, ror #12 |
![]() |
![]() |
![]() |
#11 | |
Senior Member
Iscritto dal: Oct 2002
Città: San Jose, California
Messaggi: 11794
|
Quote:
Edit: Contr'ordine, il comportamento del compilatore non e' conforme allo standard. In questa situazione: .hpp Codice:
class A { public: inline void m(); }; Codice:
inline void A::m() { } Se una funzione e' dichiarata inline in un'unita' di compilazione, il corpo deve essere definito in quell'unita'. Il comportamento del compilatore in relazione alla semantica del codice non deve cambiare a seconda delle ottimizzazioni.
__________________
"We in the game industry are lucky enough to be able to create our visions" @ NVIDIA Ultima modifica di fek : 20-12-2007 alle 14:37. |
|
![]() |
![]() |
![]() |
#12 | |
Senior Member
Iscritto dal: Nov 2002
Messaggi: 6183
|
Quote:
Anche icc della Intel ha lo stesso comportamento. Mi pare strano che due compilatori diversi hanno questo comportamento. |
|
![]() |
![]() |
![]() |
#13 | |
Senior Member
Iscritto dal: Nov 2002
Messaggi: 6183
|
Quote:
![]() |
|
![]() |
![]() |
![]() |
#14 | ||
Senior Member
Iscritto dal: Oct 2002
Città: San Jose, California
Messaggi: 11794
|
Quote:
Curioso. Comunque, non dichiarare quella funzione inline, tanto se il compilatore e' decente, nel 99.99% dei casi non cambia nulla a livello prestazionale ![]() Quote:
In generale non dichiarare mai una funzione inline se non hai veramente un buon motivo per farlo, e solo dopo che hai provato empiricamente che mettere quella funzione inline ti dia effettivamente un guadagno. Ancora piu' in generale, non fare mai assunzioni sulle ottimizzazioni, perche' scoprirai che nella maggior parte dei casi la tua assunzione e' sbagliata, spesso e volentieri quelle che pensiamo essere ottimizzazioni sono pessimizzazioni! Che succede, ad esempio, se mettere una funzione inline ti causa frequenti cache miss in un loop e il codice va in realta' piu' piano? Non puoi saperlo finche' non misuri. Mentre dichiarare una funzione online porta sicuramente degli svantaggi a livello di gestione del progetto. Innanzitutto ci hai gia' perso del tempo ![]() Poi dichiarare metodi inline significa che ti devi portare eventualmente dietro nell'header file la dichiarazione di ogni eventuale oggetto che quella funzione usa. Poi, se dichiari un metodo virtuale inline carichi di moltissimo lavoro il linker. Ho visto situazioni in progetti grossi nelle quali togliere la dichiarazione inline da un metodo ha fatto scendere il tempo di link di minuti!
__________________
"We in the game industry are lucky enough to be able to create our visions" @ NVIDIA Ultima modifica di fek : 20-12-2007 alle 14:57. |
||
![]() |
![]() |
![]() |
#15 |
Senior Member
Iscritto dal: Nov 2002
Messaggi: 6183
|
Visto che più o meno sino in tema, vorrei proporre altri quesiti.
Vorrei forzare una funzione ad essere inline, però ha circa 20 righe di codice. Anche questa è richiamata spessissimo. Quale è il flag di g++ che fa questo ? Non lo trovo più. Inoltre, a parte l'aumento di spazio dell'eseguibile, quali contro indicazioni ci sono a forzare un inlining? Ed inoltre, quale era quel flag che faceva vedere se il g++ ha messo o no inline una funzione? Grazie |
![]() |
![]() |
![]() |
#16 | |
Senior Member
Iscritto dal: Nov 2002
Messaggi: 6183
|
Quote:
|
|
![]() |
![]() |
![]() |
#17 |
Senior Member
Iscritto dal: Oct 2002
Città: San Jose, California
Messaggi: 11794
|
Se una funzione e' lunga, e' altamente probabile che anche forzando l'inline il compilatore lo ignori. Non perdere tempo e non dichiarare nulla inline, il tuo codice ti ringraziera', e molto probabilmente scoprirai che l'eseguibile risulta anche piu' veloce. Male che ti vada non cambia nulla.
__________________
"We in the game industry are lucky enough to be able to create our visions" @ NVIDIA |
![]() |
![]() |
![]() |
#18 |
Senior Member
Iscritto dal: Nov 2002
Messaggi: 6183
|
|
![]() |
![]() |
![]() |
#19 | |
Senior Member
Iscritto dal: Nov 2002
Messaggi: 6183
|
Quote:
E poi, quando una funzione è da considerarsi "lunga" per l'inline ? Questa cosa non l'ho mai capita. ![]() |
|
![]() |
![]() |
![]() |
#20 | |
Senior Member
Iscritto dal: Oct 2002
Città: San Jose, California
Messaggi: 11794
|
Quote:
![]() Prima fai le prove, fai il profiling, poi se proprio scopri he una funzione serve inline, dichiarala inline. Almeno io faccio cosi', non dichiaro mai nulla inline, poi se il profiler mi dice che una data funzione molto piccola mi sta portando via del tempo perche' il compilatore per qualche motivo ha deciso di non metterla inline da solo, allora, la forzo io. Negli ultimi cinque anni ho dichiarato inline... hmmm... forse due funzioni.
__________________
"We in the game industry are lucky enough to be able to create our visions" @ NVIDIA |
|
![]() |
![]() |
![]() |
Strumenti | |
|
|
Tutti gli orari sono GMT +1. Ora sono le: 20:53.