La dimensione dei dati in TCP / UDP fa la differenza sul tempo di trasmissione

5

Mentre discutevamo sullo sviluppo di un componente di rete per il nostro motore di gioco, un membro del nostro team ha suggerito che la trasmissione di 500 byte o 1k di dati usando UDP non fa differenza dal punto di vista delle prestazioni del sistema (il tempo necessario per trasmettere il dati).

In realtà ha detto che fino a quando non si attraversa la dimensione MTU, la dimensione dei dati trasmessi non ha importanza in quanto è sempre la stessa.

È vero per UDP? che dire di TCP?

Mi sembra semplicemente sbagliato, ma non sono un esperto di rete.

* Ho letto delle architetture di gioco di altre società e sembra che stiano tutti cercando di mantenere i dati trasmessi al minimo, rendendo le affermazioni del mio collega ancora più irragionevoli.

    
posta liortal 29.06.2013 - 12:35
fonte

5 risposte

4

Sì, le dimensioni contano. L'argomentazione del tuo collaboratore è che qualsiasi quantità di traffico fino alla MTU impiegherà lo stesso tempo per trasmettere, e questo semplicemente non è vero.

Dimentica per un minuto che hai a disposizione tutti i protocolli, solo una pipe in cui i bit vanno da una parte e (si spera) escogitano l'altra. Se la pipe può trasferire 8.000 bit al secondo, 500 byte (4.000 bit) impiegheranno mezzo secondo e 1.000 byte (8.000 bit) impiegheranno un secondo intero. Questo è vero per praticamente ogni tipo di interfaccia perché sono tutti di serie. Alcune interfacce sono parzialmente parallele in quanto possono consentire il trasferimento di più di un bit per ciclo di clock, ma una volta superato tale limite, si sta trasferendo in serie un flusso di qualunque esse siano. Quindi c'è un limite di base proprio lì.

Quando aggiungi protocolli, che sono necessari perché le pipe non sono sempre affidabili o se hai molte pipe che formano una rete, aggiungi informazioni che dicono all'implementazione del protocollo che cosa fare con il pacchetto. Queste informazioni occupano spazio (e quindi tempo di trasmissione) che non è più possibile utilizzare per i dati ed è obbligatorio in testa , perché non puoi eseguire il protocollo senza di esso.

Il tuo esempio è un pacchetto UDP / IP *, che contiene il tuo payload, un'intestazione di 8 byte aggiunta dal protocollo UDP e un'intestazione di 20 byte aggiunta dal protocollo IP. Se si inviano datagrammi a 500 byte, l'overhead a 28 byte imposto dai protocolli costituirà il 5,3% del pacchetto da 528 byte che deve essere inviato. Aumenta il carico utile fino a 1.000 byte e invii più dati personali in ogni datagramma da 1.028 byte per una percentuale di overhead del 2,7%. Se disponi di un mezzo di trasmissione con un MTU di grandi dimensioni e potresti ingoiare un pacchetto da 10.028 byte, l'overhead si ridurrebbe ulteriormente fino allo 0,3%.

TCP, essendo un protocollo più complesso di UDP, ha un'intestazione da 20 byte, che rende l'overhead totale di 40 byte quando viene eseguito su IP. Per i tuoi esempi di payload da 500 e 1.000 byte, i costi generali sarebbero pari al 7,4% e al 3,8%.

L'invio di questi pacchetti TCP / IP o UDP / IP su Ethernet aggiunge 14 byte di intestazione Ethernet, quattro byte del suo trailer e 12 byte di tempo di inattività tra i frame per un totale di 30 byte. Come avviene con i protocolli di cui sopra, payload più grandi significano meno frame e meno frame significano meno tempo speso in overhead.

Ci sono una serie di motivi per cui non si inviano semplicemente pacchetti di grandi dimensioni per mantenere bassi i costi generali. Il più grande di questi motivi è che non vuoi dover ritrasmettere un intero megabyte di dati perché hai perso sei byte da qualche parte nel mezzo. A meno che tu non sappia che il tuo mezzo di trasmissione è estremamente affidabile, è molto meglio sostenere l'overhead, quindi devi solo inviare nuovamente un frame di un kilobyte.

Il mondo reale parallelo a questo sarebbe usare camion da 53 piedi per la spedizione. È molto più economico impacchettare ognuno il più strettamente possibile di quanto lo sia per assumere i conducenti e acquistare gas per molti di loro per trasportare solo un paio di cose ciascuno.

* Quello che viene comunemente chiamato UDP è in realtà UDP su IP o UDP / IP . UDP può essere effettivamente eseguito su protocolli diversi dall'IP, ma l'IP è di gran lunga il solito.

Per affrontare il commento di dbasnett: il punto non è che UDP è eseguito su altri protocolli, è che la sua posizione nella torta del livello del protocollo significa che può essere . UDP, essendo un protocollo a livello di trasporto, presuppone che l'indirizzamento dell'host sia già stato curato dal livello di rete. Ciò significa che è possibile eseguire UDP (e solo UDP, non UDP / IP) su praticamente tutto se l'unica necessità è identificare le porte di invio e di ricezione. Funzionerebbe un collegamento seriale tra due host (senza livello di rete, dato che l'indirizzamento sarebbe implicito). Anche i frame Ethernet sarebbero necessari se gli indirizzi MAC fossero sufficienti per identificare gli host. Non sto dicendo che qualcuno lo faccia in realtà, ma uno stack di rete ben progettato consentirà la sostituzione degli strati inferiori senza che i più alti debbano conoscere o preoccuparsi.

    
risposta data 29.06.2013 - 15:08
fonte
2

Tutto dipende da ciò che consideri essere il "tempo di trasmissione". Se si tiene conto del tempo trascorso tra le chiamate a send() e recv() , ciò dipende da diversi fattori e la dimensione del pacchetto potrebbe non essere così rilevante per il calcolo. In tal caso potresti, in alcuni casi (ma ripeto, non tutti!) Affermare che qualunque cosa tu faccia - TCP, UDP, pacchetti grandi o piccoli - piccole modifiche.

Altrimenti, in alcuni scenari potrebbe essere vantaggioso avere pacchetti più piccoli per ridurre il tempo di trasmissione totale . Ad esempio: se hai una probabilità di errore elevata, e devi ritrasmettere, e usi pacchetti molto grandi, quindi molto presto il tempo di ritrasmissione dell'errore inizia a dominare il calcolo . L'aumento delle dimensioni del pacchetto aumenterà il costo e la probabilità di un errore, aumentando così il tempo di trasmissione. Nel caso estremo di un pacchetto singolo , la probabilità che un pacchetto venga danneggiato si avvicina all'unità e potrebbe essere necessario ritrasmetterlo mille volte. L'aumento del tempo è ora al 100000%. Con pacchetti mille volte più piccoli, dieci di questi sono danneggiati, si ritrasmettono solo quelli e il tempo complessivo aumenta di un solo punto percentuale (in base al protocollo di ritrasmissione).

Devi anche considerare il sovraccarico. Ogni pacchetto di byte di carico utile B che invii avrà i suoi byte O di overhead. Se si semplifica e si assume che il tempo di trasmissione fisica del pacchetto sia una funzione lineare delle sue dimensioni (non lo è), per trasmettere N byte è necessario trasmettere frame N / B, che significa (N / B) * (B + O) = N (1 + O / B) byte e kN (1 + O / B) tempo di trasmissione. Come puoi vedere, più piccolo è B, più è lungo il tempo. Un ipotetico pacchetto di dimensione zero significherebbe alcuna trasmissione di dati di payload del tutto, e quindi un tempo infinito, l'esatto contrario dello scenario di cui sopra.

Solo al livello più astratto - nessun overhead e trasmissione a tempo costante - sì, il tempo di trasmissione è k (N / B) * B, che è kN e non dipende da B. E, ancora una volta, il primo " incidente "questo modello di incontri è probabilmente una discontinuità nel colpire le dimensioni del MTU.

In generale, tuttavia, è non una rappresentazione fedele di ciò che sta realmente accadendo (pensaci in alto, pensa agli errori, pensa al sovraccarico s , al plurale. .. e questo forse su un percorso di diversi hop ), e la dimensione del pacchetto potrebbe importare molto .

Spesso, dovrai sperimentare per trovare il valore effettivo migliore, perché l'euristica semplice ("più piccolo è il migliore", "il più grande è il migliore" , ecc.) non produrrà il miglior risultato possibile.

Un test simulato

Sono qui su un laptop XP, quindi netstat -snap tcp mi fornisce alcuni dati su cui lavorare. tasso di errore. Non ho statistiche sulle dimensioni dei pacchetti, quindi presumo che siano tutti attorno ai 1500 byte anche se ovviamente non lo sono.

Suppongo che le mie statistiche forniscano un tasso di errore effettivo e che un pacchetto sia morto se un byte è morto, così che la probabilità di errore a livello di byte, Pb, è correlata alla probabilità di errore di pacchetto Pp dalla relazione "per un pacchetto per riuscire , tutti i byte devono passare intatti ", cioè,

1 - Pp = (1 - Pb)^PacketSize

Questo mi consente di ricavare Pb come 1-exp(ln(1 - Pp)/PacketSize) . A quel punto posso ricalcolare la probabilità di errore del pacchetto per qualsiasi altro PacketSize e, da quello, determinare quanto ci vorrà per trasmettere lo stesso carico utile.

In teoria potrei affermare di essere giusto , perché risulta che le dimensioni contano . Ma è pignolo - In realtà ero sbagliato , perché almeno in questo scenario le dimensioni contano molto poco :

Quindi, le dimensioni dei pacchetti possono ancora influenzare la progettazione delle applicazioni, ma certamente non a causa dei tempi di trasmissione dei dati.

    
risposta data 29.06.2013 - 14:56
fonte
1

Altre risposte hanno già commentato la parte della dimensione dei dati ma, per misurare le differenze, c'è un altro fattore rilevante:

TCP non invia solo i pacchetti di dati ma prima di inviare quelli invia pacchetti aggiuntivi per creare una connessione, quindi conferma il recupero dei pacchetti e infine invia pacchetti aggiuntivi per chiudere la connessione.

Ora il vantaggio è che ottieni la garanzia che tutti i dati sono stati ricevuti completamente e nell'ordine corretto. Costruire tali garanzie nell'applicazione è spesso più complicato rispetto all'utilizzo delle comprovate implementazioni TCP nel sistema. Anche se Google sta attualmente lavorando su QUIC , un protocollo basato su UDP per inviare contenuti Web, suggerirei di utilizzare TCP se hai bisogno di qualsiasi forma di garanzia e UDP solo quando è ok che i pacchetti arbitrari si perdano.

    
risposta data 29.06.2013 - 15:47
fonte
1

Le risposte di Blrfl e LSerni già indirizzano l'overhead (in termini di dimensioni e poi di tempo) di diverse dimensioni del pacchetto. Inoltre, affrontano già il problema degli errori.

In cima a quello ...

Un gioco online è altamente interattivo e anche i piccoli ritardi sono evidenti, se (e solo se) la tua applicazione è in grado di fare qualcosa con un chunk più piccolo (senza aspettare il pacchetto completo), allora è meglio progettare il tuo protocollo per trasmettere più pacchetti autonomi più piccoli (e per accettare l'overhead necessario), ecco perché le reti di gioco di altre aziende cercano di minimizzare le dimensioni del pacchetto: la velocità percepita è maggiore se il lag è breve .

Lascia che ti spieghi con un esempio: devi inviare trame di quattro caratteri, due casi:

  • Riduci le dimensioni di ogni pacchetto:
    • Si invia un pacchetto con tutte le texture richieste, ma in lo-res.
    • Invio di quattro pacchetti, ciascuno per la trama ad alta risoluzione di ciascun personaggio. L'applicazione utilizza immediatamente quella texture per ricreare il carattere.
  • Riduci al minimo il numero di pacchetti (e quindi di overhead e le prestazioni della rete non elaborate):
    • Invia 1 pacchetto più grande con tutte le texture ad alta risoluzione.

Come puoi immaginare, il tempo totale per il secondo caso è relativamente più basso, ma la velocità di gioco percepita è MOLTO peggiore.

In breve: il tuo collega ha torto (e non dimenticare che ogni layout sopra TCP / UDP aggiungerà sempre più overhead) ma per migliorare le prestazioni dei giochi online non si tratta di velocità di rete raw.

    
risposta data 23.11.2018 - 14:21
fonte
0

Se hai un protocollo personalizzato / un'intestazione in ogni pacchetto - > più piccolo è il pacchetto, maggiore sarà l'intestazione%!

Diciamo che la headersize è 100 byte. E diciamo che le opzioni della dimensione del pacchetto sono: 200 o 400! Se selezioni 200, l'intestazione è del 50%, se selezioni 400, l'intestazione è del 25%.

E se invii ciascun pacchetto centinaia / migliaia di volte, il problema si ridimensiona!
Se invii 10mb / sec, il 50% di esso sarà dati di intestazione con una dimensione del pacchetto di 200.

Quindi è meglio massimizzare la dimensione del pacchetto, in modo che la dimensione dell'intestazione diventi marginale, in modo da inviare più dati rispetto ai metadati! In realtà, si tratta di essere efficienti. Il suo buon senso!

Modifica: E a prescindere, "UDP" stesso è un protocollo, il che significa che i metadati vengono scambiati a prescindere. Quindi, in effetti, non importa se hai un'intestazione o meno, ci saranno sempre metadati. Quindi, per evitare spese generali, massimizza le dimensioni del pacchetto!

    
risposta data 23.11.2018 - 14:06
fonte

Leggi altre domande sui tag