traduccion threading juegos desactivar desactivado activar activado multithreading operating-system multicore hyperthreading

multithreading - juegos - Multicore+Hyperthreading: ¿cómo se distribuyen los hilos?



hyper threading intel activar (8)

La probabilidad es esencialmente 0% de que el sistema operativo no utilizará tantos núcleos físicos como sea posible. Tu sistema operativo no es estúpido. Su trabajo es programar todo, y sabe muy bien qué núcleos tiene disponible. Si ve dos subprocesos intensivos en CPU, se asegurará de que se ejecutan en dos núcleos físicos.

Editar Solo para elaborar un poco, para cosas de alto rendimiento, una vez que ingresas a MPI u otros marcos de paralelización serios, definitivamente quieres controlar lo que se ejecuta en cada núcleo.

El sistema operativo hará una especie de intento de mejor esfuerzo para utilizar todos los núcleos, pero no tiene la información a largo plazo que usted hace, que "este hilo va a funcionar por un tiempo muy largo", o que "nosotros Tendremos muchos hilos ejecutándose en paralelo ". Por lo tanto, no puede tomar decisiones perfectas, lo que significa que su hilo se asignará a un nuevo núcleo de vez en cuando, lo que significa que se encontrará con errores de caché y similares, lo que le costará un poco de tiempo. Para la mayoría de los propósitos, es lo suficientemente bueno, y ni siquiera notará la diferencia de rendimiento. Y también funciona bien con el resto del sistema, si eso importa. (En el sistema de escritorio de alguien, eso es probablemente bastante importante. En una cuadrícula con algunos miles de CPU dedicados a esta tarea, no desea particularmente jugar bien, solo quiere usar cada ciclo de reloj disponible).

Entonces, para las cosas de HPC a gran escala, sí, querrá que cada hilo permanezca en un núcleo, reparado. Pero para la mayoría de las tareas más pequeñas, en realidad no importará, y puede confiar en el programador del sistema operativo.

Estaba leyendo una reseña del nuevo Intel Atom 330, donde observaron que el Administrador de tareas muestra 4 núcleos: dos núcleos físicos, más dos más simulados por Hyperthreading.

Supongamos que tiene un programa con dos hilos. Supongamos también que estos son los únicos hilos que hacen algún trabajo en la PC, todo lo demás está inactivo. ¿Cuál es la probabilidad de que el SO ponga ambos hilos en el mismo núcleo? Esto tiene enormes implicaciones para el rendimiento del programa.

Si la respuesta es algo más que 0%, ¿hay alguna estrategia de mitigación que no sea crear más hilos?

Espero que haya respuestas diferentes para Windows, Linux y Mac OS X.

Utilizando la respuesta de sk como forraje de Google, y luego siguiendo los enlaces, encontré la función GetLogicalProcessorInformation en Windows. Habla de "procesadores lógicos que comparten recursos. Un ejemplo de este tipo de intercambio de recursos sería escenarios de hipertrofia". Esto implica que jalf es correcto, pero no es una respuesta definitiva.

Linux tiene un programador de hilos bastante sofisticado que es consciente de HT. Algunas de sus estrategias incluyen:

Balanceo pasivo de carga: si una CPU física está ejecutando más de una tarea, el planificador intentará ejecutar cualquier tarea nueva en un segundo procesador físico.

Balanceo de carga activo: si hay 3 tareas, 2 en una CPU física y 1 en la otra cuando el segundo procesador físico permanece inactivo, el planificador intentará migrarle una de las tareas.

Lo hace al intentar mantener la afinidad del hilo porque cuando un hilo migra a otro procesador físico tendrá que volver a llenar todos los niveles de caché de la memoria principal, lo que provoca un bloqueo en la tarea.

Entonces, para responder a su pregunta (al menos sobre Linux); dado 2 hilos en una máquina de doble núcleo hyperthreaded, cada hilo se ejecutará en su propio núcleo físico.


No sé sobre las otras plataformas, pero en el caso de Intel, publican mucha información sobre cómo enhebrar en su red de software Intel . También tienen un boletín informativo gratuito (The Intel Software Dispatch) que puede suscribirse por correo electrónico y ha tenido muchos de esos artículos últimamente.


Puede asegurarse de que ambos subprocesos se programen para las mismas unidades de ejecución dándoles una afinidad de procesador. Esto se puede hacer en Windows o Unix, ya sea a través de una API (para que el programa pueda solicitarla) o a través de interfaces administrativas (para que un administrador pueda configurarlo). Por ejemplo, en WinXP puede usar el Administrador de tareas para limitar qué procesador (es) lógico (s) puede ejecutar un proceso.

De lo contrario, la programación será esencialmente aleatoria y puede esperar un uso del 25% en cada procesador lógico.


Un sistema operativo sano intentará programar tareas intensivas desde el punto de vista computacional en sus propios núcleos, pero surgen problemas cuando se inicia el cambio de contexto. Los sistemas operativos modernos todavía tienen una tendencia a programar cosas en núcleos donde no hay trabajo en el tiempo de programación, pero esto puede hacer que los procesos en aplicaciones paralelas se intercambien de núcleo a núcleo de forma bastante liberal. Para aplicaciones paralelas, no desea esto, porque pierde datos que el proceso podría haber estado usando en las memorias caché en su núcleo. La gente usa la afinidad del procesador para controlar esto, pero en Linux, la semántica de sched_affinity () puede variar mucho entre distros / kernels / vendors, etc.

Si está en Linux, puede controlar portátilmente la afinidad del procesador con la Biblioteca de Afinidad del Procesador Portable Linux (PLPA) . Esto es lo que OpenMPI usa internamente para asegurarse de que los procesos se programen en sus propios núcleos en sistemas multinúcleo y multisono; acaban de derivar el módulo como un proyecto independiente. OpenMPI se usa en Los Alamos entre muchos otros lugares, por lo que este es un código bien probado. No estoy seguro de cuál es el equivalente en Windows.


He estado buscando algunas respuestas sobre la programación de subprocesos en Windows, y tengo información empírica que publicaré aquí para cualquiera que se tropiece con esta publicación en el futuro.

Escribí un sencillo programa de C # que lanza dos hilos. En mi caja cuádruple para Windows 7, vi algunos resultados sorprendentes.

Cuando no forcé la afinidad, Windows extendió la carga de trabajo de los dos hilos en los cuatro núcleos. Hay dos líneas de código que están comentadas, una que vincula un hilo a una CPU y otra que sugiere una CPU ideal. La sugerencia parecía no tener ningún efecto, pero establecer la afinidad del hilo hizo que Windows ejecutara cada hilo en su propio núcleo.

Para ver mejor los resultados, compile este código utilizando el compilador de libre disponibilidad csc.exe que viene con el cliente de .NET Framework 4.0 y ejecútelo en una máquina con múltiples núcleos. Con la línea de afinidad del procesador comentada, el Administrador de tareas mostró los subprocesos repartidos en los cuatro núcleos, cada uno de los cuales funciona aproximadamente al 50%. Con afinidad establecida, los dos subprocesos alcanzaron un máximo de dos núcleos al 100%, con los otros dos núcleos inactivos (que es lo que esperaba ver antes de ejecutar esta prueba).

EDITAR: Inicialmente encontré algunas diferencias en el rendimiento con estas dos configuraciones. Sin embargo, no he podido reproducirlos, así que edité esta publicación para reflejar eso. Todavía encontré el hilo de afinidad interesante ya que no era lo que esperaba.

using System; using System.Collections.Generic; using System.Linq; using System.Diagnostics; using System.Runtime.InteropServices; using System.Threading.Tasks; class Program { [DllImport("kernel32")] static extern int GetCurrentThreadId(); static void Main(string[] args) { Task task1 = Task.Factory.StartNew(() => ThreadFunc(1)); Task task2 = Task.Factory.StartNew(() => ThreadFunc(2)); Stopwatch time = Stopwatch.StartNew(); Task.WaitAll(task1, task2); Console.WriteLine(time.Elapsed); } static void ThreadFunc(int cpu) { int cur = GetCurrentThreadId(); var me = Process.GetCurrentProcess().Threads.Cast<ProcessThread>().Where(t => t.Id == cur).Single(); //me.ProcessorAffinity = (IntPtr)cpu; //using this line of code binds a thread to each core //me.IdealProcessor = cpu; //seems to have no effect //do some CPU / memory bound work List<int> ls = new List<int>(); ls.Add(10); for (int j = 1; j != 30000; ++j) { ls.Add((int)ls.Average()); } } }


Esta es una pregunta muy buena y relevante. Como todos sabemos, un núcleo hiper-enhebrado no es una verdadera CPU / núcleo. En cambio, es una CPU / núcleo virtual (de ahora en adelante diré núcleo). Se supone que el programador de CPU de Windows a partir de Windows XP es capaz de distinguir núcleos hyperthreading (virtuales) de núcleos reales. Podrías imaginarte entonces que en este mundo perfecto los maneja "bien" y no es un problema. Estarías equivocado.

La recomendación de Microsoft para optimizar un servidor BizTalk de Windows 2008 recomienda desactivar HyperThreading. Esto sugiere, para mí, que el manejo de núcleos hiperhilo no es perfecto y, a veces, los hilos obtienen una porción de tiempo en un núcleo con hiperproceso y sufren la penalización (una fracción del rendimiento de un núcleo real, 10% I '' Supongo, y Microsoft adivina 20-30%).

Referencia de artículo de Microsoft donde sugieren deshabilitar HyperThreading para mejorar la eficiencia del servidor: http://msdn.microsoft.com/en-us/library/cc615012(BTS.10).aspx

Es la SEGUNDA recomendación después de la actualización del BIOS, así de importante es su consideración. Ellos dicen:

DE MICROSOFT:

" Deshabilitar hyper-threading en BizTalk Server y computadoras SQL Server

Es fundamental que Hyper-Threading esté desactivado para las computadoras BizTalk Server. Esta es una configuración del BIOS, que normalmente se encuentra en la configuración del procesador de la configuración del BIOS. Hyper-Threading hace que el servidor parezca tener más procesadores / núcleos de procesador de lo que realmente hace; sin embargo, los procesadores de hiperproceso suelen proporcionar entre un 20 y un 30% del rendimiento de un procesador físico / núcleo de procesador. Cuando BizTalk Server cuenta el número de procesadores para ajustar sus algoritmos de autoajuste; los procesadores de hiperproceso hacen que estos ajustes sean asimétricos, lo que es perjudicial para el rendimiento general. "

Ahora dicen que se debe a que arroja los algoritmos de autoajuste, pero luego mencionan los problemas de contención (sugiriendo que es un problema de programación más grande, al menos para mí). Léelo como quieras, pero creo que lo dice todo. HyperThreading era una buena idea cuando estaba con sistemas de CPU individuales, pero ahora es solo una complicación que puede dañar el rendimiento en este mundo de múltiples núcleos.

En lugar de deshabilitar por completo HyperThreading, puede utilizar programas como Process Lasso (gratis) para establecer las afinidades predeterminadas de CPU para procesos críticos, de modo que sus subprocesos nunca se asignen a CPU virtuales.

Entonces ... No creo que nadie sepa realmente cuán bien el Programador de CPU de Windows maneja las CPU virtuales, pero creo que es seguro decir que XP lo maneja peor, y lo han mejorado gradualmente desde entonces, pero todavía no es perfecto. De hecho, NUNCA puede ser perfecto porque el sistema operativo no tiene ningún conocimiento de qué subprocesos son mejores para poner en estos núcleos virtuales más lentos. Ese puede ser el problema allí, y por qué Microsoft recomienda deshabilitar HyperThreading en entornos de servidores.

Además, recuerde que incluso SIN HyperThreading, existe el problema de la "vibración central". Si puede mantener un hilo en un solo núcleo, eso es bueno, ya que reduce las penalizaciones de cambio de núcleo.


La posibilidad de que el SO envíe 2 hilos activos al mismo núcleo es cero a menos que los hilos estén atados a un núcleo específico (afinidad de hilos).

Las razones detrás de esto están principalmente relacionadas con HW:

  • El sistema operativo (y la CPU) quiere usar la menor cantidad de energía posible para que ejecute las tareas de la manera más eficiente posible para ingresar a un estado de bajo consumo lo antes posible.
  • Ejecutar todo en el mismo núcleo hará que se caliente mucho más rápido. En condiciones patológicas, el procesador puede sobrecalentarse y reducir su reloj para que se enfríe. El calor excesivo también hace que los ventiladores de la CPU giren más rápido (piense en computadoras portátiles) y genere más ruido.
  • El sistema nunca está realmente inactivo. Los ISR y los DPC se ejecutan cada ms (en la mayoría de los sistemas operativos modernos).
  • La degradación del rendimiento debido al salto de subprocesos desde el núcleo al núcleo es insignificante en el 99,99% de las cargas de trabajo.
  • En todos los procesadores modernos, el último nivel de caché se comparte, por lo tanto, cambiar de núcleo no es tan malo.
  • Para sistemas Multi-socket (Numa), el sistema operativo minimizará el salto de socket a socket para que un proceso permanezca "cerca" de su controlador de memoria. Este es un dominio complejo cuando se optimiza para tales sistemas (decenas / cientos de núcleos).

Por cierto, la forma en que el sistema operativo conoce la topología de la CPU es a través de ACPI, una interfaz proporcionada por el BIOS.

En resumen, todo se reduce a las consideraciones de potencia del sistema (duración de la batería, consumo de energía, ruido de la solución de refrigeración).