2013-07-21 6 views
7

Ho trovato che la mia latenza di lettura/scrittura MMIO è irragionevolmente alta. Spero che qualcuno possa darmi qualche suggerimento.MMIO latenza lettura/scrittura

Nello spazio del kernel, ho scritto un semplice programma per leggere un valore di 4 byte nell'indirizzo BAR0 di un dispositivo PCIe. Il dispositivo è un NIC PCIe Intel 10G e collegato al bus PCIe x16 sul mio server Xeon E5. Io uso rdtsc per misurare il tempo che intercorre tra l'inizio della MMIO leggere e alla fine, un frammento di codice simile a questo:

vaddr = ioremap_nocache(0xf8000000, 128); // addr is the BAR0 of the device 
rdtscl(init); 
ret = readl(vaddr); 
rmb(); 
rdtscl(end); 

mi aspetto il tempo trascorso tra (fine, init) deve essere inferiore a 1us , dopo tutto, i dati che attraversano il collegamento dati PCIe dovrebbero essere solo pochi nanosecondi. Tuttavia, i risultati dei miei test mostrano il lease 5.5use per leggere un dispositivo PCIe MMIO. Mi chiedo se questo sia ragionevole. Cambio il mio codice in remote the memory barrier (rmb), ma continuo ad ottenere 5 in latenza.

Questo documento fa riferimento alla misurazione della latenza PCIe. Di solito è meno di 1us. www.cl.cam.ac.uk/~awm22/.../miller2009motivating.pdf Devo eseguire una configurazione speciale come kernel o dispositivo per ottenere una latenza di accesso MMIO inferiore? o qualcuno ha esperienze prima?

risposta

-1

Se la scheda NIC deve passare attraverso la rete, magari tramite gli interruttori, per ottenere i dati da un host remoto, 5.5us è un tempo di lettura ragionevole. Se stai leggendo un registro nel dispositivo PCIe locale, dovrebbe essere inferiore a 1us. Non ho alcuna esperienza con Intel NIC 10G, ma lo ha funzionato con Infiniband e schede personalizzate.

+0

Misuro meno di 1 us per leggere una parola nella BAR di un dispositivo sul bus PCIe locale. Non sono sicuro del motivo per cui il mio commento non è stato votato perché sto solo confermando che i risultati del documento sono realistici. La BAR è stata mappata nello spazio utente, abbiamo appena letto l'indirizzo. Stai contando anche il tempo di ioremap_nocache()? Come parte del mio lavoro, leggo i registri nelle BAR nei sistemi in tutta la stanza, e ci vogliono meno di 5,5 noi. Sto usando RDMA su Mellanox FDR Infiniband con uno switch IB tra i sistemi. –

2

5usec è fantastico! Fai questo in un ciclo statisticamente e potresti trovare valori molto più grandi.

Ci sono diversi motivi per questo. Le BAR di solito non sono memorizzabili nella cache e non sono prefetchabili: controlla le tue usando pci_resource_flags(). Se la BAR è marcata in cache e quindi compatibile con la cache, il processo per garantire che tutte le CPU abbiano lo stesso valore memorizzato nella cache potrebbe essere un problema.

In secondo luogo, leggere io è sempre un affare non pubblicato. La CPU deve bloccarsi fino a quando non ottiene il permesso di comunicare su alcuni bus di dati e si blocca un po 'di più fino a quando i dati arrivano su detto bus. Questo bus è fatto per apparire come memoria, ma in realtà non lo è e lo stallo potrebbe essere un'attesa indaffarata e non interrompibile ma non produttiva mai. Quindi mi aspetterei che la latenza nel caso peggiore sia molto più alta di 5us anche prima di iniziare a considerare l'azzeramento delle attività.