Di solito scrivevo molto assembler nel corso della giornata. Non è solo che i compilatori sono migliorati, è che la maggior parte dell'hardware ora ha un sacco di logica dedicata all'esecuzione di codice del codice. La vera micro-issue è la pianificazione, la maggior parte delle istruzioni del computer impiegano più clock di macchina per produrre un risultato e un carico di memoria che perde la cache può richiedere diverse centinaia! Quindi l'idea era di programmare altre istruzioni per fare qualcosa di utile, invece di aspettare un risultato. E le macchine moderne possono emettere diverse istruzioni per periodo di clock. Una volta che abbiamo iniziato a eseguire l'esecuzione fuori ordine HW, ho scoperto che provare a ottenere grandi prestazioni con la codifica manuale è diventato un gioco di mug. Per prima cosa, l'HW out-of-order non avrebbe eseguito le istruzioni nel tuo ordine accuratamente predisposto, la nuova architettura HW ha ridotto la penalità di una programmazione software inoptimale, sufficiente a far sì che il compilatore fosse in genere in una percentuale inferiore delle prestazioni. Inoltre ho scoperto che i compilatori ora stavano implementando trucchi noti, ma di complessità, come lo srotolamento, il caricamento dal basso, il pipelining del software, ecc. La linea di fondo, devi lavorare davvero molto, saltare alcuni di questi trucchi e il compilatore ti batte. Usali tutti e il numero di istruzioni per assemblatore che ti servono aumenta di più volte!
Probabilmente, ancora più importante, la maggior parte dei problemi di prestazioni non riguardano i tassi di emissione delle istruzioni, ma il recupero dei dati nella CPU. Come accennato in precedenza, la latenza della memoria è ora centinaia di cicli e la CPU può eseguire diverse istruzioni per periodo di clock, quindi
a meno che il programma - e specialmente le strutture dati siano progettate in modo tale che il tasso di hit della cache sia eccessivamente alto, la microtuning a livello di istruzioni non avrà alcun risultato. Proprio come
i militari dicono che i dilettanti parlano tattiche, i professionisti parlano di logistica. La programmazione delle prestazioni è ora più del 90% della logistica (dati in movimento). E questo è difficile da quantificare, poiché la gestione moderna della memoria ha in genere più livelli di cache e le pagine di memoria virtuale sono gestite da un'unità hardware chiamata TLB. Anche l'allineamento di basso livello degli indirizzi diventa importante, come dati effettivi
i trasferimenti, non sono in unità di byte o anche lunghi a 64 bit, ma sono disponibili in unità
delle linee della cache. Quindi la maggior parte delle macchine moderne ha un hardware che cerca di prevedere quale linea della cache manchi di cui si potrebbe aver bisogno nel prossimo futuro e rilasciare prefetches automatici per portarli nella cache. Quindi la realtà
è che con le moderne CPU i modelli di prestazioni sono così complessi da risultare quasi incomprensibili. Anche i simulatori hardware dettagliati non possono mai eguagliare la logica esatta dei chip, così esatta
la sintonizzazione è semplicemente impossibile più.
C'è ancora un posto per alcuni codici mano. Librerie matematiche (come la funzione exp), così come le più importanti operazioni di algebra lineare (come la moltiplicazione della matrice) sono ancora in genere codificate a mano
da esperti che lavorano per il fornitore di hardware (ad esempio Intel o AMD o IBM), ma probabilmente
servono solo un paio di programmatori di assemblatori di prima qualità per mega-computer corp.