Domanda

Sto usando ARM926EJS. Sto ottenendo il 20% in più di velocità di memoria nel test di copia della memoria, senza Linux (proprio come un eseguibile di Introduzione). Ma in Linux lo stesso codice è più lento del 20%.

Il codice è

 
/// Below code just performs burst mode memcopy test.        
void asmcpy(void *a, void *b, int iSize)
{
   do
  {
    asm volatile (
             "ldmia %0!, {r3-r10} \n\t"
             "stmia %0!, {r3-r10} \n\t"
             :"+r"(a), "+r"(b)
             :
             :"r"(r3),"r"(r4),"r"(r5),"r"(r6),"r"(r7),"r"(r8),"r"(r9),"r"(r10)
             );
  }while(size--)
}

Ho verificato che nessun altro processo sta impiegando tempo CPU su Linux. (Ho controllato questo con l'uso del comando time, Mostra che tempo reale è uguale a tempo usr )

Per favore, dimmi quale può essere il problema con Linux?

Grazie & amp; Saluti.

AGGIUNTO:

il mio codice di test è

int main()
{
  int a[320 * 120], b[320 * 120];

 for(int i=0; i != 10000; i++)
 {
   /// Size is divided by 8 because our memcpy function performs 8 integer load stores in the iteration
   asmcpy(a, b, (320 * 120) / 8);
 }
}

Il file eseguibile Guida introduttiva è un file bin che viene inviato alla RAM tramite la porta seriale ed esegue direttamente saltando a quell'indirizzo nella RAM. (senza la necessità di un sistema operativo)

AGGIUNTO.

Non ho visto differenze di prestazioni simili su altri processori. Stavano usando la RAM SD, questo processore sta usando DDR Ram. Può essere un motivo?

aggiunto.   La cache dei dati non è abilitata per iniziare il codice e la cache dei dati viene acquisita in modalità Linux, quindi idealmente tutti i dati dovrebbero essere memorizzati nella cache e accessibili senza alcuna latenza RAM, ma comunque Linux è lento del 20%.

AGGIUNTO:   Il mio microcontrollore è LPC3250. Entrambi i test sono stati testati sulla stessa RAM DDR esterna.

È stato utile?

Soluzione

Questo chip ha un MMU, quindi è probabile che Linux lo stia usando per gestire la memoria. Forse solo abilitarlo introduce qualche hit di prestazione. Inoltre, Linux utilizza una strategia di allocazione della memoria lenta, assegnando le pagine di memoria a un processo solo quando lo colpisce per la prima volta. Se stai copiando un grosso pezzo di memoria, la MMU genererà errori di pagina per chiedere al kernel di allocare una pagina all'interno del tuo ciclo. Su un processore di fascia bassa, tutti questi switch di contesto causano svuotamenti della cache e introducono un notevole rallentamento.

Se il tuo sistema è abbastanza piccolo, prova una versione senza MMU di Linux (come uClinux ). Forse ti permetterebbe di usare un chip più economico con prestazioni simili. Sui sistemi embedded, ogni centesimo conta.

aggiornamento: alcuni dettagli extra:

Ogni processo Linux ottiene i propri mapping di memoria, all'inizio questo include solo il kernel e (forse) il codice eseguibile. Tutto il resto del lineare da 4 GB (su 32 bit) sembra disponibile, ma non ci sono pagine RAM assegnate a loro. Non appena leggi o scrivi un indirizzo di memoria non allocato, la MMU segnala un errore di pagina e passa al kernel. Il kernel vede che ha ancora molte pagine RAM libere, quindi ne sceglie una, la assegna al punto errato e ritorna al codice, che termina l'istruzione interrotta. Il prossimo non fallirà perché l'intera pagina (in genere 4KB) è già assegnata; ma dopo alcune iterazioni, colpirà un altro spazio non assegnato e la MMU invocherà di nuovo il kernel.

Altri suggerimenti

Come stai eseguendo i tempi? Non c'è un codice di temporizzazione nel tuo esempio.

Sei sicuro di non misurare il tempo di caricamento / scaricamento del processo?

La velocità di clock del processore è la stessa in entrambi i casi?

Se si utilizza SDRAM esterna, i tempi della RAM sono uguali in entrambi i casi?

La cache di dati è abilitata in entrambi i casi?

Clifford

Per iniziare non è " solo un eseguibile " ;. È necessario un codice per impostare il registro del controller DDR.

Se anche la cache è abilitata, allora deve essere la MMU. Penso su ARM926EJS, non puoi avere cache di dati senza MMU.

Credo che ogni cambio di contesto si traduca in un flush della cache, perché la cache è praticamente indicizzata, praticamente taggata e Kernel e Userspace non condividono lo stesso spazio di indirizzi, quindi probabilmente avrai molto più flush di cache indesiderato nel OS.

Ecco un paper con alcuni aspetti costo dello svuotamento della cache VIVT quando si esegue Linux

Quale microcontrollore (non solo quale CPU ARM) stai usando?

È possibile che nell'esecuzione non Linux l'array che si sta testando sia RAM sul dispositivo microcontrollore stesso mentre nel test Linux l'array in fase di test si trova nella RAM esterna? Di solito si accede alla RAM interna molto più velocemente della RAM esterna - questo potrebbe spiegare il rallentamento del test di Linux, anche se la memorizzazione dei dati nella cache è abilitata solo per l'esecuzione di Linux.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top