Efficientemente "spostando" i dati verso l'alto attraverso uno stack di comunicazione

2

Ho implementato uno stack di protocolli applicativi che sposta un flusso di dati in entrata verso l'alto attraverso diversi livelli, come segue:

  1. copie un segmento TCP da un buffer del sistema operativo a my_buffer .
  2. dopo aver identificato un limite di un record, divide il record in my_buffer in stringhe separate da tabulazioni che sono copiate in deque<string> my_deque (piuttosto che in un vettore perché devo immediatamente far apparire una coppia di campi dalla parte anteriore)
  3. copie my_deque in vector<string> my_records[n] dove viene presentato senza ulteriore copia all'applicazione.

Mi chiedo se sia meglio attenersi a un'architettura pulita (stratificazione) e pagare il prezzo (qualunque cosa sia) di copiare il carico utile da un livello all'altro, o se ci sono alcune semplici ottimizzazioni che le persone usano.

È consuetudine utilizzare buffer separati per livelli separati, oppure è qualcosa che può essere facilmente ottimizzato senza compromettere pericolosamente l'indipendenza dei livelli?

    
posta Chap 25.08.2013 - 03:46
fonte

3 risposte

4

Ho avuto una certa esperienza nell'ottimizzare il codice di rete, sia nativo che .NET. Le cose che amo sono importanti:

  1. Quanti messaggi / secondo vengono trasferiti?
  2. Quanti megabyte / secondo vengono trasferiti?
  3. Questa è una lingua raccolta dalla spazzatura? (Nel tuo caso, no)
  4. Quali sono i requisiti della tua app?

Se 1 è "piccolo" (50 al secondo o meno?), allora il tuo codice di rete francamente non è ciò che qualcuno noterà. Dovresti invece ottimizzare per la compatibilità con il tocco o migliorare i flussi di lavoro dei tuoi clienti; avrai più soldi per il dollaro. Per la scala server, dovrai preoccuparti di più dell'affinità dei thread piuttosto che delle copie di memoria. Se è grande, un certo numero di SO ora include speciali API di rete per gestire il numero di shear delle chiamate - Windows, per esempio, ha le API RIO in Winsock proprio per questo.

Se 2 è "grande" (> 100 megabyte / secondo), è necessario preoccuparsi di eseguire copie aggiuntive sui server, ma solo a causa della pressione della memoria. In particolare per un ambiente VM, la pressione della memoria sarà spesso ciò che impedisce alla VM di gestire più client, il che porta immediatamente a dover eseguire più VM.

Se 3 è vero e # 1 è "grande" e sei su un server, devi preoccuparti del blocco della memoria e della durata dell'oggetto. Ma non lasciarti guidare da te per evitare i linguaggi GC; ci sono molti grandi programmi che fanno networking in lingue GC.

E # 4 è veramente importante. Hai requisiti di latenza estremi come gli operatori di borsa ad alta velocità? Hai misurato la tua performance?

Raramente incontro programmi client-side in cui l'ottimizzazione del numero di buffer copiati ha fatto la differenza che gli utenti potevano vedere. Per i server, in genere prima vedo che c'è un collo di bottiglia inaspettato che colpisce molto prima di ogni altra cosa. Ci sono un sacco di tecniche per aiutare - scalabilità lato ricezione, varie tecniche asincrone e chiamate speciali di gestione del buffer.

TL; DR: se non sei un server, mantieni il tuo codice pulito. Se lo sei, misura prima, ottimizza secondo. E "ottimizzare" include molte tecniche, di cui "copia meno memoria" è una.

    
risposta data 25.08.2013 - 07:30
fonte
1

Invece di risolvere nuovamente questo problema, ti consiglio vivamente di provare il link . È stato sviluppato dalla persona che gestiva link internamente su Google ed è specificamente progettato per sfruttare tutti le buone idee che ha avuto mentre lo faceva su come rendere le cose più veloci per la comunicazione di rete. (Gli stessi buffer di protocollo sono già molto più efficienti di quello che la maggior parte delle persone fa sul filo e sono ampiamente utilizzati internamente da Google proprio per questo motivo.)

    
risposta data 25.08.2013 - 06:09
fonte
0

Evita di copiare a tutti i costi. Se analizzi la cronologia delle implementazioni del protocollo di rete, scoprirai che, di volta in volta, le vere ottimizzazioni della larghezza di banda derivano dalla creazione di "zero copy" protocolli e algoritmi. I moderni sistemi operativi lavorano molto duramente per passare pacchetti a monte dal gestore di interrupt fino all'IP e, a volte, a livelli più alti senza copiare i dati, per ottime ragioni.

    
risposta data 25.08.2013 - 21:39
fonte

Leggi altre domande sui tag