|
|
|
|
Strumenti |
27-01-2020, 13:06 | #21 | |
Senior Member
Iscritto dal: Apr 2001
Città: Milano
Messaggi: 3594
|
Quote:
capisco che l'idea è folle ma interessante Poi oramai sono lanciato e credo sia solo una questione di regolazioni del tutto. Come già detto, funzionicchia con 30 thread ed impiega un tempo abbastanza umano rispetto a quando aprivo un aolo socket ed attendevo, ora è una pacchia. Nella prima versione avevo messo un timer per chiudere la socket anzi tempo (dopo 2 secondi) in quanto, esiste una sorta di attesa di 21 secondi se dall'altra parte non risponde nessuno ed è un tempo che ho letto, non è modificabile almeno, io non ci sono riuscito. Avevo provato anche col ping ma mi sono detto: e se ci sono server che se ne fregano del ping? questi non li vedo. Diciamo che in questa prima versione testo solo la porta 80 ma nella successiva, intendo testare anche qualche porta in più se la 80 non mi risponde. |
|
27-01-2020, 15:21 | #22 | |
Senior Member
Iscritto dal: May 2001
Messaggi: 12580
|
Quote:
Anche abbreviando il timeout sulle connect() sull'ordine delle centinaia di millisecondi (assumendo IP Italiani) un eventuale ciclo di connect() il tuo throughput sarebbe comunque limitato ad una frequenza di 1/timeout tentativi di connessione al secondo. Se assumi un timeout di 1s, un singolo thread tenterà 1 connessione al secondo, assumendo che tu abbia 30 thread e non ci siano overhead di gestione particolarmente significativi, 30 connessioni al secondo. Come puoi vedere più abbassi il timeout e più aumenta il throughput, inteso come numero di tentativi che puoi fare nell'unità di tempo. Infatti la cosa ideale è avere timeout=0 che è quello che ti suggerisco io . Con socket non bloccanti o con le raw socket, puoi lanciare N SYN in parallelo a più server senza dover necessariamente aspettare che questi rispondano. Questo significa che anche un thread singolo può lanciare in brevissimo tempo tanti tentativi di connessione. Il motivo è che non sei più limitato dal tuo codice quanto dai cicli di clock della CPU (inteso anche come overhead del SO) e dalla banda di rete. |
|
28-01-2020, 08:29 | #23 |
Senior Member
Iscritto dal: Apr 2001
Città: Milano
Messaggi: 3594
|
grazie per le info.
Sto provano con 65535 thread e si ferma a 1519 thread in esecuzione, molto probabilmente si esaurisce lo stack. Mi chiedevo chi gestiche la concorrenza sulla scheda tra le varie connessioni: ci pensa l'SO visto che io istanzio tutti i thread e non me ne occupo? Non vedendo messaggi di errore, a parte quelli delle connessioni mancate, devo pensare che sia l'SO a gestire la concorrenza. |
28-01-2020, 10:46 | #24 | |
Senior Member
Iscritto dal: May 2001
Messaggi: 12580
|
Quote:
|
|
28-01-2020, 11:00 | #25 | |
Senior Member
Iscritto dal: Apr 2001
Città: Milano
Messaggi: 3594
|
Quote:
Tra una send ed una receive io imposto un certo tempo di attesa, non sto usando gli eventi in quanto ero convinto che se si usano socket bloccanti questi non erano necessari, ma ho idea che mi sto sbagliando. Se setto 250 ms tra send e receive mi arrivano dati, se setto 1000 ms non arriva più nulla, come se il thread successivo o precedente svuoti la cache per lascar posto alle successive chiamate. Cioè è come se il sistema mi stesse dicendo: se ti svegli prendi i dati altrimenti li perdi. Ho idea che la miglior soluzione sia settare gli eventi ed è meglio che non mi chieda come fa il sistema a gestire tutte queste chiamate, che casotto |
|
28-01-2020, 11:59 | #26 | |
Senior Member
Iscritto dal: May 2001
Messaggi: 12580
|
Quote:
Quindi non hai bisogno di timers in questo caso a meno che appunto non vuoi forzare un timeout dopo un certo tempo che non ricevi nulla. A quanto imposti la size della receive()? Tieni presente che appunto se chiedi di ricevere 100 bytes, la receive blocca fino a quando il buffer lato SO non contiene 100 bytes. Il che significa che se la risposta della GET è di 99 bytes, non vieni svegliato. Questo mediamente, poi bisognerebbe capire se Windows ha qualche euristica particolare per cui magari si sveglia comunque dopo un certo tempo. PS: con TCP non può mai succedere che perdi i dati a meno di leggerli e scartarli volontariamente. |
|
28-01-2020, 12:52 | #27 | |
Senior Member
Iscritto dal: Apr 2001
Città: Milano
Messaggi: 3594
|
Quote:
Se ad un certo punto non arriva nulla esco dal while per evitare deadlock. Di TCP sapevo che non perdi nulla, di sicuro sbaglio io qualcosa nrl mio codice. Però ho notato se i thread si fermano a 10, non perdo alcun dato. Molto probabilmente il ciclo che ho settato io per la lettura ha qualche problema quando tutto diventa più lento per via del maggior traffico enerato da molti thread. Comunque, ottimi consigli, grazie. |
|
28-01-2020, 17:12 | #28 | ||
Senior Member
Iscritto dal: May 2001
Messaggi: 12580
|
Quote:
Riguardo al timeout, di regola puoi impostarlo direttamente sulla socket usando la funzione setsockopt() abbinata al parametro SO_RCVTIMEO. Probabilmente ci sarà l'analoga funzione Borland. Quote:
Cioè da quello che ho capito io gestisci ogni socket con 1 thread, corretto? Ovvero, non hai niente di condiviso tra i thread, giusto? Può darsi pure che ad un certo punto rallenta la rete e quindi ti trovi a ricevere i dati più tardi. |
||
28-01-2020, 17:30 | #29 | |
Senior Member
Iscritto dal: Apr 2001
Città: Milano
Messaggi: 3594
|
Quote:
è come hai intuito, ogni thread ha il suo buffer e socket personale, quindi non dovrebbero darsi fastidio in alcun modo cioè, l'unica risorsa in concorrenza è la scheda di rete ma mi hai detto che ci pensa l'SO e meno male che è così. Ultima modifica di misterx : 28-01-2020 alle 17:35. |
|
02-02-2020, 10:33 | #30 |
Senior Member
Iscritto dal: May 2001
Messaggi: 12580
|
|
02-02-2020, 17:00 | #31 | |
Senior Member
Iscritto dal: Apr 2001
Città: Milano
Messaggi: 3594
|
Quote:
ZMap ZMap è un veloce scanner di rete a pacchetto singolo ottimizzato per sondaggi di rete su Internet. Su un computer con una connessione Gigabit, ZMap può eseguire la scansione dell'intero spazio degli indirizzi IPv4 pubblico in meno di 45 minuti. Con una connessione 10gigE e PF_RING, ZMap può scansionare lo spazio degli indirizzi IPv4 in 5 minuti. Comunque il mio progetto va avanti e istanziando n thread risulta piuttosto veloce, i 136 anni sono solo un ricordo lontano. Tempo di ottimizzarlo e se interessa vi dico le tempistiche che ottengo. |
|
07-02-2020, 11:29 | #32 |
Senior Member
Iscritto dal: Apr 2001
Città: Milano
Messaggi: 3594
|
sto provando con 50 thread ma qualcuno mi ha detto che non ha senso superare il numero di core della CPU in quanto i thread vengono messi in attesa ma qui, secondo me, entra in ballo la statistica o sbaglio?
Potrei avere 50 thread in attesa oppure 50 che lavorano ma in questo caso è impossibile perchè non ho una CPU con 50 core, oppure la maggior parte che stanno fermi o viceversa. Quale strategia migliore? Scusate, ho buttato li alcuni pensieri sparsi per capire come si ragiona in questi casi. |
07-02-2020, 21:00 | #33 | |
Senior Member
Iscritto dal: May 2001
Messaggi: 12580
|
Quote:
Tuttavia, ha senso aumentare il numero di thread quando puoi sovrapporre la computazione all'I/O e quindi molti di quei thread andrebbero spesso a dormire in attesa di avere dati pronti. Ad esempio, hai diversi thread che fanno read() e bloccano in attesa di ricevere il dato, quando bloccano vengono messi in pausa dallo scheduler che assegna la CPU ad uno tra i thread pronti. In questo modo, concedendo l'esecuzione ad altri thread, mascheri la latenza di ricezione dei dati da parte degli altri e nel frattempo fai lavoro utile. Ovvio che oltre un certo numero sopraggiungono problemi di overhead dovuti ai cambi di contesto e al fatto che diventa più probabile che hai diversi thread pronti che ritardano la loro esecuzione perché non gli viene assegnata CPU dal SO. Dipende dall'applicazione. Comunque te ne dovresti accorgere abbastanza facilmente, perché ad un certo punto se aumentando il numero di thread le prestazioni non aumentano o peggio diminuiscono vuol dire che sei arrivato a saturazione. |
|
08-02-2020, 07:44 | #34 | |
Senior Member
Iscritto dal: Apr 2001
Città: Milano
Messaggi: 3594
|
Quote:
ottime osservazioni. Però se rendessi tutto parallelo dovrei rinunciare ai socket bloccanti, reintrodurre quelli non bloccanti e gestire i vari eventi in quanto questi si attivano solo quando c'è qualcosa da fare. Grazie 1000 |
|
08-02-2020, 09:51 | #35 | |
Senior Member
Iscritto dal: Jan 2008
Messaggi: 8406
|
Quote:
Nella pratica si possono lanciare centinaia di goroutine senza doversi preoccupare di misurare i livelli di saturazione. Ovviamente l'ho buttata lì come informazione utile. Lungi da me forzare misterx a riscrivere il tutto in Go |
|
08-02-2020, 10:27 | #36 |
Senior Member
Iscritto dal: Apr 2001
Città: Milano
Messaggi: 3594
|
quasi quasi, come mi è stato suggerito qualche post fa, farei prima a dialogare direttamente col driver della scheda di rete e togliere di mezzo l'SO con tutte le sue regole, forse impiegherei meno tempo.
|
08-02-2020, 11:05 | #37 | |
Senior Member
Iscritto dal: Jan 2008
Messaggi: 8406
|
Quote:
Interfacciarsi col driver non ti aiuterebbe coi limiti sui thread. E ovviamente dovresti implementare tutto quello che sta al di sopra del livello datalink. |
|
08-02-2020, 11:48 | #38 |
Senior Member
Iscritto dal: Apr 2001
Città: Milano
Messaggi: 3594
|
|
08-02-2020, 11:57 | #39 | |
Senior Member
Iscritto dal: Apr 2001
Città: Milano
Messaggi: 3594
|
Quote:
Parto con 250 thread ed ogni volta che uno termina il suo compito un altro prende il suo posto. Ho provato con 5 e si addormenta tutto nel senso che, attendono il timeout per qualche ragione, se si sale l'attesa diminuisce. A volte le soluzioni migliori si nascondono nella semplicità |
|
08-02-2020, 12:09 | #40 | ||
Senior Member
Iscritto dal: Jan 2008
Messaggi: 8406
|
Quote:
Quote:
E vedo un flusso pressochè costante di connessioni che terminano a breve distanze le une dalle altre. Su 5 thread è assai probabile incappare in 5 tartughe. |
||
Strumenti | |
|
|
Tutti gli orari sono GMT +1. Ora sono le: 00:00.