Sto profilando un collo di bottiglia nel mio codice (una funzione mostrata di seguito) che viene chiamato diverse milioni di volte. Potrei usare suggerimenti per aumentare le prestazioni. I numeri XXXs
sono stati presi da Sleepy.Ottimizza le prestazioni del loop
Compilato con Visual Studio 2013, /O2
e altre impostazioni di rilascio tipiche.
indicies
è in genere da 0 a 20 valori e altri parametri hanno la stessa dimensione (b.size() == indicies.size() == temps.size() == temps[k].size()
).
1: double Object::gradient(const size_t j,
2: const std::vector<double>& b,
3: const std::vector<size_t>& indices,
4: const std::vector<std::vector<double>>& temps) const
5: 23.27s {
6: double sum = 0;
7: 192.16s for (size_t k : indices)
8: 32.05s if (k != j)
9: 219.53s sum += temps[k][j]*b[k];
10:
11: 320.21s return boost::math::isfinite(sum) ? sum : 0;
13: 22.86s }
Qualche idea?
Grazie per i suggerimenti ragazzi. Qui sono stati i risultati che ho ottenuto dalle suggestioni:
ho trovato interessante il fatto che il passaggio a cbegin()
e cend()
ha avuto un impatto così grande. Immagino che il compilatore non sia intelligente come potrebbe. Sono contento dell'urto, ma sono curioso di sapere se c'è più spazio qui attraverso lo srotolamento o la vettorizzazione.
Per chi fosse interessato, ecco il mio punto di riferimento per isfinite(x)
:
boost::isfinite(x):
------------------------
SPEED: 761.164 per ms
TIME: 0.001314 ms
+/- 0.000023 ms
std::isfinite(x):
------------------------
SPEED: 266.835 per ms
TIME: 0.003748 ms
+/- 0.000065 ms
Poiché si tratta di una parte di codice molto piccola, è possibile provare a eseguire la procedura in linea. –
J non cambia mai, quindi se si capovolge il vettore di temps, è possibile issare l'accesso di J out of the loop. – user4581301
Anche i tempi di trasposizione renderebbero molto più accessibile la cache. – tzaman