Borealid's answer incluye prueba y descubra, que es imposible de superar como se aconseja.
Pero quizás haya más para probar esto de lo que pueda pensar: desea que sus hilos eviten la contención de datos siempre que sea posible. Si los datos son completamente de solo lectura, entonces es posible que vea el mejor rendimiento si sus hilos acceden a datos "similares", asegurándose de recorrer los datos en pequeños bloques a la vez, de modo que cada hilo acceda a los datos del same pages over and over again. Si los datos son completamente de solo lectura, entonces no hay problema si cada núcleo obtiene su propia copia de las líneas de caché. (Aunque esto podría no aprovechar al máximo el uso de la caché de cada núcleo.)
Si los datos son de ninguna manera modificada, a continuación, verá mejoras significativas en el rendimiento si mantiene los hilos distancia entre sí, por un montón .La mayoría de las memorias caché almacenan datos a lo largo de cache lines, y desea desesperadamente mantener cada cache line from bouncing among CPUs para un buen rendimiento. En ese caso, es posible que desee mantener los diferentes subprocesos ejecutándose en datos que están muy separados para evitar que se topen entre sí.
Entonces, si está actualizando los datos mientras trabajaba en él, le recomendaría tener N o 2 * N hilos de ejecución (para N núcleos), comenzando con TAMAÑO/N * M como punto de partida, para los hilos 0 a M. (0, 1000, 2000, 3000, para cuatro hilos y 4000 objetos de datos). Esto le dará la mejor oportunidad de alimentar diferentes líneas de caché para cada núcleo y permitir que las actualizaciones procedan sin rebotar en la línea de caché:
+--------------+---------------+--------------+---------------+--- ...
| first thread | second thread | third thread | fourth thread | first ...
+--------------+---------------+--------------+---------------+--- ...
Si eres no actualización de los datos mientras se trabaja en ella, es posible que desee iniciar o N 2 * N hilos de ejecución (para n núcleos), comenzando con 0, 1, 2, 3 , etc. y moviendo cada uno hacia delante por N o 2 * N elementos con cada iteración. Esto permitirá que el sistema de caché busque cada página de la memoria una vez, llene las memorias caché de la CPU con datos casi idénticos, y esperemos que mantenga cada núcleo poblado con datos recientes.
+-----------------------------------------------------+
| 1 2 3 4 1 2 3 4 1 2 3 4 1 2 3 4 1 2 3 4 1 2 3 4 ... |
+-----------------------------------------------------+
También recomiendo el uso de sched_setaffinity(2)
directamente en el código de la fuerza los diferentes hilos a sus propios procesadores. En mi experiencia, Linux apunta al keep each thread on its original processor tanto que no migrará tareas a otros núcleos que de otro modo estarían inactivos.
¡Eso sería un montón de hilos! Creo que querías decir la cantidad de núcleos, ¿verdad? – dasblinkenlight
Suponiendo que todas las operaciones en los enteros pueden suceder completamente al mismo tiempo, simplemente se divide por el número de núcleos. Es mucho más difícil estimar cuándo el trabajo no se puede hacer al mismo tiempo. –
¿Están estos subprocesos realizando alguna E/S (bloqueo) o cualquier operación de bloqueo, como las comunicaciones de red o la base de datos? Si no, entonces es probable que el número óptimo de núcleos sea N. En su caso, 4. De lo contrario, vale la pena experimentar con 2N o 3N, mientras que un hilo está haciendo E/S, otro hilo puede funcionar. – selbie