Quando si crea il codice di profilazione a livello di istruzioni di assemblaggio, cosa significa realmente la posizione del puntatore di istruzioni dato che le CPU moderne non eseguono le istruzioni in serie o in ordine? Ad esempio, si assuma il seguente codice assembly x64:Profilo livello di istruzione: il significato del puntatore di istruzioni?
mov RAX, [RBX]; // Assume a cache miss here.
mov RSI, [RBX + RCX]; // Another cache miss.
xor R8, R8;
add RDX, RAX; // Dependent on the load into RAX.
add RDI, RSI; // Dependent on the load into RSI.
Quale istruzione trascorrerà la maggior parte del tempo sull'indicatore di istruzioni? Posso pensare di buoni argomenti per tutti loro:
mov RAX, [RBX]
sta prendendo probabilmente 100s di cicli perché è un cache miss.mov RSI, [RBX + RCX]
richiede anche 100 s di cicli, ma probabilmente viene eseguito in parallelo con l'istruzione precedente. Cosa significa per il puntatore dell'istruzione essere su uno o l'altro di questi?xor R8, R8
probabilmente si esegue fuori ordine e termina prima che i carichi di memoria finiscano, ma il puntatore di istruzioni potrebbe rimanere qui fino a quando tutte le precedenti istruzioni non sono state completate.add RDX, RAX
genera uno stallo della pipeline perché è l'istruzione in cui il valore diRAX
viene effettivamente utilizzato dopo un carico di cache-miss lento in esso.add RDI, RSI
si blocca anche perché dipende dal carico inRSI
.
Puoi spiegare come funzionano i contatori di monitoraggio delle prestazioni dell'hardware in tale contesto? Per esempio. Linux ha il sottosistema 'perf' che fornisce profili statistici basati su PMC. Il kernel sta solo generando un interrupt ad alta frequenza che poi - secondo la tua molto bella analogia - collassa la funzione wave IP e legge i PMC, e quindi assegnerebbe i valori correnti di quei PMC all'IP attualmente trovato (dopo l'onda funzione collasso)? E poi resettare le PMC e riprendere dall'interrupt? – oberstet