Ho un'implementazione di una classe X, che ha due puntatori a due informazioni. Ho scritto una nuova implementazione, classe Y, che ha un solo puntatore a una struttura che contiene le due informazioni insieme come membri adiacenti. I metodi di X e Y di solito hanno solo bisogno di manipolare una delle informazioni, ma forniscono un metodo get() che restituisce un puntatore al secondo pezzo (in questo caso la classe X restituisce semplicemente il puntatore a quel pezzo e la classe Y restituisce l'indirizzo del secondo membro della struttura). Nell'uso normale, le chiamate ai metodi di X e Y si alternano tra le chiamate a get() e il lavoro su quel secondo pezzo restituito.C++, modi per confrontare i miglioramenti nella localizzazione della cache?
Mi aspetto che nelle situazioni di vita reale ci dovrebbe essere un miglioramento delle prestazioni, ora che le due parti di informazioni sono l'una accanto all'altra in memoria nell'implementazione di classe Y (perché sono membri adiacenti di una struttura), ma io Non vedo alcuna differenza nei benchmark che ho scritto (intercalando le chiamate ai metodi di X e Y con il lavoro sui loro secondi pezzi in grandi loop). Ho il sospetto che ciò avvenga perché tutto si adatta alla cache in entrambi i casi nei miei test. Non voglio ancora provare questo nella mia app reale perché la semantica di X e Y si differenziano in altri modi sottili non correlati a questa ottimizzazione e il porting dell'applicazione usando sarà un po 'di lavoro, e questi benchmark dovrebbero aiutare a giustificare il fatto lavorare in primo luogo.
Qual è il modo migliore per osservare la differenza di prestazioni a causa di una migliore localizzazione della cache? Se faccio un mucchio di lavoro fittizio su un array uguale alla dimensione della cache tra una chiamata e l'altra è sufficiente? O voglio lavorare su un array leggermente meno della dimensione della cache, in modo che il lavoro sulle mie istanze della mia classe causi l'ingresso e l'uscita dalla cache? Non sono sicuro di come codificare qualcosa che sia robusto contro le ottimizzazioni del compilatore e le diverse dimensioni della cache.
'Perché' non è davvero il problema qui - la domanda è abbastanza chiaramente per valutare la localizzazione della cache. Non credo che "perché" aggiunga davvero qualcosa alla discussione, e il suo meglio è supporre che Joseph sappia quello che sta facendo. – Justicle
Il "perché" è sempre importante, almeno IMHO. "Mi aspetto che nelle situazioni della vita reale ci dovrebbe essere un miglioramento delle prestazioni" che mi dice che Joseph sta cercando di accelerare le cose. "Non voglio ancora provarlo nella mia vera app", il che suggerisce ancora più pesantemente che il suo obiettivo finale è una performance migliore, e sta cercando di farlo attraverso una località migliorata - ecco perché ho consigliato altri corsi per migliorare le prestazioni. Comunque, @Joseph, se sono andato nella direzione sbagliata qui, per favore ignora. ;-) [E in tal caso, cachegrind è quello che vuoi] –
Sto scrivendo una classe puntatore intelligente che è fondamentalmente senza algoritmo. L'ho ottimizzato con g-prof fino al punto in cui cose come se un ramo esiste (un if) o un attributo intero spuria possono determinare se la mia classe batte la vecchia implementazione. Questo è uno dei pochi casi in cui si applicano sicuramente le micro-ottimizzazioni;) –