Borealid's answer include test e scoprire, che è impossibile da battere come consiglio.
Ma forse c'è ancora di più da testare su ciò che si potrebbe pensare: si desidera che i thread evitino la contesa per i dati laddove possibile. Se i dati sono interamente di sola lettura, è possibile che si ottengano le migliori prestazioni se i thread accedono a dati "simili", assicurandosi di scorrere i dati in piccoli blocchi alla volta, in modo che ogni thread acceda ai dati da same pages over and over again. Se i dati sono completamente di sola lettura, non c'è alcun problema se ogni core riceve la propria copia delle linee della cache. (Anche se questo potrebbe non sfruttare al massimo la cache di ogni core.)
Se i dati sono in qualche modo modificati, allora vedrete miglioramenti significativi delle prestazioni se tenete i fili di distanza uno dall'altro, da molto .La maggior parte delle cache memorizza i dati lungo cache lines e si desidera disperatamente mantenere ogni cache line from bouncing among CPUs per buone prestazioni. In tal caso, potresti voler mantenere i diversi thread in esecuzione su dati che sono effettivamente distanti tra loro per evitare di incontrarsi mai l'uno con l'altro.
Quindi: se si stanno aggiornando i dati mentre si lavora su di esso, si consiglia di avere N o 2 * N thread di esecuzione (per N core), iniziando con SIZE/N * M come punto di partenza, per i thread da 0 a M. (0, 1000, 2000, 3000, per quattro thread e 4000 oggetti dati.) Ciò ti darà la migliore possibilità di alimentare diverse linee di cache per ogni core e di consentire agli aggiornamenti di continuare senza il rimbalzo della linea cache:
+--------------+---------------+--------------+---------------+--- ...
| first thread | second thread | third thread | fourth thread | first ...
+--------------+---------------+--------------+---------------+--- ...
Se siete non aggiornamento dei dati mentre si lavora su di esso, si potrebbe desiderare di iniziare a N o 2 * N fili di esecuzione (per N core), li iniziando con 0, 1, 2, 3 ecc. e spostando ciascuno avanti di N o 2 * N elementi con ogni iterazione. Ciò consentirà al sistema cache di recuperare ogni pagina dalla memoria una volta, popolando le cache della CPU con dati quasi identici, e si spera che ogni core venga riempito con nuovi dati.
+-----------------------------------------------------+
| 1 2 3 4 1 2 3 4 1 2 3 4 1 2 3 4 1 2 3 4 1 2 3 4 ... |
+-----------------------------------------------------+
ho anche consigliamo di utilizzare sched_setaffinity(2)
direttamente nel codice per forza i diversi thread per i propri processori. Nella mia esperienza, Linux punta a keep each thread on its original processor così tanto che non migra le attività su altri core altrimenti inutilizzati.
Sarebbe un sacco di discussioni! Penso che tu intenda il numero di core, giusto? – dasblinkenlight
Supponendo che tutte le operazioni sugli interi possano avvenire completamente simultaneamente, è sufficiente dividere per il numero di core. È molto più difficile valutare quando il lavoro non può essere svolto contemporaneamente. –
Questi thread eseguono qualsiasi I/O (bloccante) o qualsiasi operazione di blocco come le comunicazioni di rete o il database? Se no, allora è probabile che il numero ottimale di core sia N. Nel tuo caso, 4. Altrimenti, vale la pena sperimentare 2N o 3N - mentre un thread sta facendo I/O, un altro thread può funzionare. – selbie