Se non si rompe non ripararlo. Non è rotto.
Un problema principale sono gli accessi non allineati. Passano da cattivi a pessimi a seconda dell'architettura su cui si sta eseguendo. Molto ha a che fare con i programmatori, alcuni con i compilatori.
Il modo più economico per correggere memcpy è di non utilizzarlo, mantenere i dati allineati su confini piacevoli e utilizzare o creare un meme di alternativa che supporti solo copie di blocco perfettamente allineate. Ancora meglio sarebbe avere un interruttore del compilatore per sacrificare lo spazio del programma e ram per motivi di velocità. persone o linguaggi che utilizzano molte strutture in modo tale che il compilatore generi internamente chiamate a memcpy o qualunque sia l'equivalente di una lingua, le loro strutture cresceranno in modo tale che vi sia un pad interposto o inserito all'interno. Una struttura di 59 byte potrebbe invece diventare 64 byte. malloc o un'alternativa che fornisce solo puntatori a un indirizzo allineato come specificato. ecc. ecc.
È molto più semplice fare tutto da solo. Un malloc allineato, strutture che sono multipli della dimensione dell'allineamento. La tua memcpy che è allineata, ecc. Essendo così semplice perché l'hardware dovrebbe rovinare i loro progetti, compilatori e utenti? non esiste un caso aziendale per questo.
Un'altra ragione è che le cache hanno modificato l'immagine. il tuo dram è accessibile solo in una dimensione fissa, 32 bit a 64 bit, qualcosa del genere, qualsiasi accesso diretto più piccolo di quello è un enorme successo in termini di prestazioni. Metti la cache di fronte al risultato della performance che va giù, qualsiasi lettura-modifica-scrittura avviene nella cache con la modifica che consente di modificare più volte per una singola lettura e scrittura di dram. Si vuole comunque ridurre il numero di cicli di memoria nella cache, sì, e si può ancora vedere il guadagno di prestazioni lisciando quello con la cosa del cambio (8 bit prima marcia, 16 bit seconda marcia, 32 bit terza marcia, 64 velocità di crociera bit, 32 bit spostamento verso il basso, a 16 bit scalare, 8 bit scalare)
Non posso parlare per Intel, ma so che gente come ARM hanno fatto ciò che si sta chiedendo un
ldmia r0!,{r2,r3,r4,r5}
per esempio è ancora quattro trasferimenti a 32 bit se il core utilizza un'interfaccia a 32 bit. ma per le interfacce a 64 bit se allineato su un boundry a 64 bit diventa un trasferimento a 64 bit con una lunghezza di due, un insieme di trattative tra le parti e due parole a 64 bit spostate. Se non è allineato su un limite a 64 bit, diventa tre trasferimenti un singolo 32 bit, un singolo 64 bit e un singolo 32 bit. Bisogna stare attenti, se questi sono registri hardware che potrebbero non funzionare a seconda del progetto della logica di registro, se supporta solo trasferimenti a 32 bit singoli non si può usare quella istruzione contro quello spazio di indirizzamento. Non capisco perché proverai comunque qualcosa del genere.
L'ultimo commento è ... fa male quando faccio questo ... beh, non farlo. Non un singolo passaggio nelle copie di memoria. il corollario di questo è che nessuno può modificare il design dell'hardware per rendere più semplice l'uso di una copia di memoria per l'utente, che il caso d'uso è così piccolo che non esiste. Prendi tutti i computer utilizzando quel processore in esecuzione a piena velocità giorno e notte, misurato rispetto al fatto che tutti i computer siano passati da una copia mem a un altro codice ottimizzato per le prestazioni. È come paragonare un granello di sabbia alla larghezza della terra. Se sei single stepping, dovrai comunque fare un passo avanti per qualunque sia la nuova soluzione, se ce ne fosse una. per evitare enormi latenze di interrupt, la memcpy accordata a mano inizierà comunque con un if-then-else (se una copia troppo piccola va inserita in un piccolo insieme di codice srotolato o un ciclo di copia in byte), quindi inserire una serie di copie di blocco a una certa velocità ottimale senza orribili dimensioni di latenza. Dovrai ancora fare un passo avanti.
fare debugging a step singolo da compilare avvitato, lento, codice comunque, il modo più semplice per risolvere un singolo passo attraverso il problema memcpy è quello di avere il compilatore e il linker quando gli viene detto di compilare per il debug, compilare e collegamento con una memcpy non ottimizzata o una libreria alternativa non ottimizzata in generale. gnu/gcc e llvm sono open source, puoi farli fare quello che vuoi.
Risposta di uscita: perché semplicemente non lo fanno, e come risultato nessuno scrive codice in questo modo, e quindi non c'è motivo per farlo ... (il ciclo continua) –
@BillyONeal: non lo faccio pensa così Per ogni nuova funzionalità che aggiungono, non è ancora stato scritto alcun codice che lo utilizza. – ybungalobill
Sì, ma quando viene aggiunta una nuova funzione, questa viene aggiunta per mostrare prestazioni migliori in un'area o nell'altra. Ottimizzare questo non ha senso per i fornitori di CPU perché i compilatori non emetteranno il codice come esso. –