Relativo al mio other question, ora ho modificato il solutore matrice sparse per utilizzare il metodo SOR (Successive Over-Relaxation). Il codice è ora la seguente:Perché la velocità di questo risolutore SOR dipende dall'input?
void SORSolver::step() {
float const omega = 1.0f;
float const
*b = &d_b(1, 1),
*w = &d_w(1, 1), *e = &d_e(1, 1), *s = &d_s(1, 1), *n = &d_n(1, 1),
*xw = &d_x(0, 1), *xe = &d_x(2, 1), *xs = &d_x(1, 0), *xn = &d_x(1, 2);
float *xc = &d_x(1, 1);
for (size_t y = 1; y < d_ny - 1; ++y) {
for (size_t x = 1; x < d_nx - 1; ++x) {
float diff = *b
- *xc
- *e * *xe
- *s * *xs - *n * *xn
- *w * *xw;
*xc += omega * diff;
++b;
++w; ++e; ++s; ++n;
++xw; ++xe; ++xs; ++xn;
++xc;
}
b += 2;
w += 2; e += 2; s += 2; n += 2;
xw += 2; xe += 2; xs += 2; xn += 2;
xc += 2;
}
}
Ora la cosa strana è: se io aumento omega
(il fattore di rilassamento), la velocità di esecuzione inizia a dipendere drammaticamente sui valori all'interno delle varie matrici!
Per omega = 1.0f
, il tempo di esecuzione è più o meno costante. Per omega = 1.8
, la prima volta, in genere occorrono, per esempio, 5 millisecondi per eseguire questo step()
10 volte, ma questo gradualmente aumenterà fino a circa 100 ms durante la simulazione. Se imposto lo omega = 1.0001f
, vedo un leggero aumento dei tempi di esecuzione; più alto è il omega
, più veloce sarà il tempo di esecuzione durante la simulazione.
Poiché tutto questo è incorporato nel solutore di fluidi, è difficile trovare un esempio indipendente. Ma ho salvato lo stato iniziale e rieseguito il risolutore in quello stato ogni volta che passo, oltre a risolvere il passo temporale attuale. Per lo stato iniziale era veloce, per le successive fasi temporali più lentamente. Poiché tutto il resto è uguale, ciò dimostra che la velocità di esecuzione di questo codice dipende dai valori in questi sei array.
Questo è riproducibile su Ubuntu con g ++, così come su Windows 7 a 64 bit durante la compilazione per 32-bit con VS2008.
Ho sentito che i valori NaN e Inf possono essere più lenti per i calcoli in virgola mobile, ma non ci sono né NaN né Infs. È possibile che la velocità dei calcoli mobili dipenda altrimenti dai valori dei numeri di input?
Sei sicuro di non misurare altri codepath che dipendono dai valori dei calcoli? – ebo
Se si continuano a riscontrare problemi di prestazioni, considerare l'utilizzo di una GPU per questi calcoli. Le GPU sono ottime per il lavoro a matrice sparsa. – Mark
@ebo: ho usato l'orologio in tempo reale su Linux per misurare solo questa chiamata. Quindi sì, ne sono abbastanza sicuro. – Thomas