¿Por qué un programa requeriría un número mínimo específico de núcleos de CPU?


55

¿Es posible escribir código (o software completo, en lugar de un fragmento de código) que no funcione correctamente cuando se ejecuta en una CPU que tiene menos de N núcleos? Sin verificarlo explícitamente y fallar a propósito:

SI (noOfCores <4) ENTONCES no funciona correctamente a propósito

Estoy viendo los requisitos mínimos del sistema de un juego ( Dragon Age: Inquisition ), y establece un mínimo de una CPU de cuatro núcleos. Muchos jugadores dicen que NO se ejecuta en CPU de dos núcleos y INCLUSO en Intel Core i3 con dos núcleos físicos y dos lógicos. Y NO es un problema de potencia informática.

Según tengo entendido, los hilos están completamente aislados de la CPU por el sistema operativo ya que eso no se puede hacer.

Solo para aclarar las cosas:

NO estoy preguntando "¿Puedo averiguar el número de núcleos de CPU del código y fallar a propósito?" ... Tal código sería mal intencionado (lo obliga a comprar una CPU más costosa para ejecutar un programa, sin la necesidad de potencia computacional). Le pido que su código, por ejemplo, tenga cuatro hilos y falle cuando dos hilos se ejecutan en el mismo núcleo físico (sin verificar explícitamente la información del sistema y fallar a propósito) .

En resumen, ¿puede haber un software que requiera múltiples núcleos, sin necesidad de potencia informática adicional que provenga de múltiples núcleos? Solo requeriría N núcleos físicos separados.


11
Si lees mi pregunta detenidamente, verás que no preguntan lo mismo.
uylmz

21
Dado que se puede recuperar el número de núcleos, se puede comparar con N, y si esa comparación se evalúa como verdadera, el código puede hacer lo que quiera, incluido, entre otros, comportarse de manera no anunciada. ¿Cuál es tu pregunta?

3
¿Estás seguro de que el problema está realmente y directamente relacionado con el número de núcleos? ¿Tal vez el juego mencionado se basa parcialmente en una característica solo (correctamente) proporcionada por la CPU con al menos 4 núcleos?
mgoeminne

25
Tenga en cuenta que los "requisitos mínimos del sistema" suelen ser "requisitos mínimos del sistema para funcionar con un rendimiento aceptable", especialmente con los juegos. Es muy posible que Dragon Age pueda, en teoría, ejecutarse en una sola caja central, pero si lo hiciera, mostraría una caída masiva de cuadros. Por lo tanto, requieren este número de núcleos no para obligarlo a comprar hardware, sino para evitar quejas de calidad de los usuarios de hardware de gama baja.
Gort the Robot

3
@Sebb: Creo que estás en algo: si 4 núcleos físicos se correlacionan con tener más caché que 2 físicos / 4 lógicos, entonces el juego podría atragantarse en máquinas 2x2 sin alcanzar sus límites de potencia de procesamiento porque le falta todo el caché hora. La prueba sería encontrar una CPU con 2x2 núcleos y cargas de caché, o 4 núcleos y poca caché, y ver qué sucede.
Steve Jessop

Respuestas:


45

Es posible hacer esto "por accidente" con el uso descuidado de la afinidad central. Considere el siguiente pseudocódigo:

  • comenzar un hilo
  • en ese hilo, descubra en qué núcleo se está ejecutando
  • establecer su afinidad de CPU a ese núcleo
  • comenzar a hacer algo computacionalmente intensivo / bucle para siempre

Si inicia cuatro de ellas en una CPU de dos núcleos, entonces algo falla con la configuración de afinidad central o termina con dos hilos que acaparan los núcleos disponibles y dos hilos que nunca se programan. En ningún momento ha preguntado explícitamente cuántos núcleos hay en total.

(Si tiene subprocesos de larga ejecución, la configuración de la afinidad de la CPU generalmente mejora el rendimiento)

La idea de que las compañías de juegos están "obligando" a las personas a comprar hardware más caro sin una buena razón no es muy plausible. Solo puede perderlos clientes.

Editar: esta publicación ahora tiene 33 votos a favor, ¡lo cual es bastante dado que se basa en conjeturas educadas!

Parece que la gente tiene DA: I para ejecutar, mal, en sistemas de doble núcleo: http://www.dsogaming.com/pc-performance-analyses/dragon-age-inquisition-pc-performance-analysis/ Ese análisis menciona que la situación mejora enormemente si se activa hyperthreading. Dado que HT no agrega más unidades de problema de instrucción o caché, simplemente permite que se ejecute un subproceso mientras otro está en una parada de caché, lo que sugiere fuertemente que está vinculado a la cantidad pura de subprocesos.

Otro póster afirma que cambiar los controladores de gráficos funciona: http://answers.ea.com/t5/Dragon-Age-Inquisition/Working-solution-for-Intel-dual-core-CPUs/td-p/3994141 ; Dado que los controladores gráficos tienden a ser una miserable colmena de escoria y villanía, esto no es sorprendente. Un conjunto notorio de controladores tenía un modo "correcto y lento" versus "rápido e incorrecto" que se seleccionaba si se llamaba desde QUAKE.EXE. Es completamente posible que los controladores se comporten de manera diferente para diferentes números de CPU aparentes. Quizás (volviendo a la especulación) se usa un mecanismo de sincronización diferente. ¿Mal uso de spinlocks ?

El "mal uso de las primitivas de bloqueo y sincronización" es una fuente muy común de errores. (El error que se supone que estoy mirando en el trabajo mientras escribo esto es "bloqueo si se cambia la configuración de la impresora al mismo tiempo que finaliza el trabajo de impresión").

Edición 2: los comentarios mencionan que el sistema operativo intenta evitar el hambre de hilos. Tenga en cuenta que el juego puede tener su propio cuasi-programador interno para asignar trabajo a subprocesos, y habrá un mecanismo similar en la propia tarjeta gráfica (que es efectivamente un sistema multitarea propio). Las posibilidades de un error en uno de esos o la interacción entre ellos son bastante altas.

www.ecsl.cs.sunysb.edu/tr/ashok.pdf (2008) es una tesis de posgrado sobre una mejor programación para tarjetas gráficas que menciona explícitamente que normalmente utilizan la programación por orden de llegada, que es fácil de implementar en sistemas no preventivos. ¿Ha mejorado la situación? Probablemente no.


1
Sí, hay dos partes para responder a esta pregunta: la afinidad de la CPU le permite a uno codificar algo que haría de esto un requisito técnico en Windows, la respuesta alternativa es que los sistemas en tiempo real definitivamente pueden requerir tales cosas. +1 por ser la única persona en mencionar la afinidad de la CPU, que es realmente el culpable más probable de lo que se pregunta aquí.
Jimmy Hoffa

3
¿Qué puede salir mal si configura la afinidad al núcleo actual? Con la multitarea preventiva, el hilo de espera se programará a menos que el actual tenga la máxima prioridad posible ("tiempo real" en Windows). Vería otro escenario: a cada uno de los 4 subprocesos se les asigna una afinidad estáticamente definida de 1,2,4,8, en cuyo caso los dos últimos subprocesos nunca se programarán (aunque no estoy seguro de si establecer afinidad como efectiva) cero va a tener éxito).
Ruslan

@Ruslan ¿Quizás intentar establecer una afinidad no válida bloqueará la aplicación en primer lugar?
Luaan

1
Así @Luaan que no es que arriesgada operación para llevar a estrellarse. Máximo lo que esperaría es un error devuelto por el sistema operativo. Acabo de comprobar, en Linux me sale el error "Argumento inválido". No sé qué diría Windows.
Ruslan

@Ruslan Todos los principales sistemas operativos desde hace más de una década han incluido código para evitar el hambre de hilos (generalmente al aumentar la prioridad de un hilo después de que no se haya ejecutado durante el tiempo suficiente).
Voo

34

Podría ser necesario tener 4 núcleos porque la aplicación ejecuta cuatro tareas en subprocesos paralelos y espera que finalicen casi simultáneamente.

Cuando cada subproceso es ejecutado por un núcleo separado y todos los subprocesos tienen exactamente la misma carga de trabajo computacional, es muy probable (pero lejos de estar garantizado) que terminen aproximadamente al mismo tiempo. Pero cuando dos hilos se ejecutan en un núcleo, el tiempo será mucho menos predecible porque el núcleo cambiará el contexto entre los dos hilos todo el tiempo.

Los errores que se producen debido a la sincronización inesperada del subproceso se denominan " condiciones de carrera ".

En el contexto del desarrollo del juego, una arquitectura plausible con este tipo de problema podría ser una en la que diferentes características del juego se simulan en tiempo real por diferentes hilos de CPU. Cuando cada característica se ejecuta en un núcleo propio, todas se simulan con aproximadamente la misma velocidad. Pero cuando dos características se ejecutan en un núcleo, ambas solo se simularán la mitad de rápido que el resto del mundo del juego, lo que podría causar todo tipo de comportamientos extraños.

Tenga en cuenta que una arquitectura de software que depende de subprocesos independientes que se ejecutan con tiempos específicos es extremadamente frágil y una señal de muy mala comprensión de la programación concurrente. Hay características disponibles en prácticamente todas las API de subprocesos múltiples para sincronizar subprocesos explícitamente para evitar este tipo de problemas.


11
Pero cualquier juego tiene una dependencia frágil de poder completar todos los cálculos para el siguiente fotograma a tiempo para representarlo con una frecuencia razonable. Incluso si sus 4 hilos están sincronizados correctamente, puede ser imposible renderizar de manera oportuna, y no hay ningún beneficio en un juego que sea computacionalmente correcto pero no se pueda reproducir debido al retraso y al tartamudeo.
Inútil

1
@ Inútil: Eso no es realmente cierto. Puede, por ejemplo, cuadros de búfer o datos de simulación para ocultar cualquier tartamudeo, y hay diseños concurrentes que son más consistentes. Hacer todo su procesamiento en X tiempo y asegurar la sincronización exacta de ese procesamiento son asuntos diferentes.
DeadMG

23
"Una arquitectura de software que depende de subprocesos independientes que se ejecutan con tiempos específicos es extremadamente frágil", razón por la cual no puedo imaginar un juego que no se ejecute en absoluto con 2 núcleos, pero que funcione de manera confiable con 4 núcleos. Incluso con 4 núcleos, el tiempo será impredecible, por lo que la condición de carrera también ocurriría, incluso con menos frecuencia.
svick

8
@svick, por supuesto. Pero la pregunta es "¿es posible?" no "¿está cuerdo?"
user253751

55
Cualquier código con este tipo de "condiciones de carrera" está completamente roto , sin importar en cuántos núcleos lo ejecute. (Especialmente porque no hay absolutamente ninguna garantía de qué más se está ejecutando en el sistema). Dudo seriamente que esta sea la causa, dada la facilidad con la que se tropezaría el juego incluso en un sistema hexacore ...
DevSolar

16

Es poco probable que estos "requisitos mínimos" representen algo por debajo del cual el juego no se ejecutará. Mucho más probable es que representen algo por debajo del cual el juego no se ejecutará con un rendimiento aceptable. Ninguna compañía de juegos quiere lidiar con muchos clientes quejándose del mal desempeño cuando lo están ejecutando en un solo núcleo de 1 Ghz, incluso si el software podría ejecutarse técnicamente. Por lo tanto, probablemente diseñen deliberadamente para fallar con fuerza en cajas con menos núcleos de los que les darían un rendimiento aceptable.

Una métrica importante en el rendimiento del juego es la velocidad de fotogramas. Por lo general, se ejecutan a 30 o 60 cuadros por segundo. Esto significa que el motor del juego tiene que representar la vista actual desde el estado del juego en un período de tiempo fijo. Para lograr 60 fps, tiene un poco más de 16 ms para hacer esto. Los juegos con gráficos de alta gama están extremadamente vinculados a la CPU, por lo que hay una gran toma y daca entre tratar de impulsar una mayor calidad (que lleva más tiempo) y la necesidad de mantenerse en este presupuesto de tiempo. Por lo tanto, el presupuesto de tiempo para cada cuadro es extremadamente ajustado.

Debido a que el presupuesto de tiempo es limitado, el desarrollador idealmente quiere acceso exclusivo a uno o más núcleos. También es probable que quieran poder hacer sus tareas de renderizado en un núcleo, exclusivamente, ya que es lo que debe hacerse con ese presupuesto de tiempo, mientras que otras cosas, como calcular el estado mundial, suceden en un proceso separado donde no entrometerse.

En teoría, podría agrupar todo esto en un solo núcleo, pero luego todo se vuelve mucho más difícil. De repente, debes asegurarte de que todo lo relacionado con el estado del juego suceda lo suficientemente rápido y permita que tu renderizado suceda. No puede simplemente convertirlos en dos subprocesos de software porque no hay forma de hacer que el sistema operativo entienda que "el subproceso A debe completar una cantidad X de trabajo en 16 ms, independientemente de lo que haga el subproceso B".

Los desarrolladores de juegos no tienen ningún interés en hacerte comprar nuevo hardware. La razón por la que tienen requisitos del sistema es que el costo de soportar máquinas de gama baja no vale la pena.


Si bien esto es cierto, sucede que puede comprar hardware de doble núcleo que sea lo suficientemente potente como para lograr más en un marco de tiempo dado que el hardware de cuatro núcleos descrito en las especificaciones mínimas. ¿Por qué el vendedor no enumeraría dicho hardware como aceptable, una decisión que solo puede perderles las ventas?
Jules

44
Lo que hay que comparar no es 2 vs 4 núcleos. Esencialmente es de 1 a 3 núcleos, ya que la CPU # 0 estará más o menos vinculada por el controlador de gráficos y los DPC. También hay importantes efectos de caché y migración si se suscribe en exceso una CPU con varios tipos de tareas en el sistema de trabajo de un juego moderno típico. El requisito está ahí porque Frostbite (motor DA: I) está diseñado desde cero con un ajuste muy cuidadoso que requiere un número particular de núcleos.
Lars Viklund

66
@LarsViklund Parece que sabes más detalles que nadie aquí. ¿Has considerado poner una respuesta juntos?
Gort the Robot

1
"Es poco probable que estos" requisitos mínimos "representen algo por debajo del cual el juego no se ejecutará. Mucho más probable es que representen algo por debajo del cual el juego no se ejecutará con un rendimiento aceptable". - El G3258 de Intel es un procesador de doble núcleo muy potente ampliamente utilizado por los jugadores que es capaz de ejecutar juegos con la misma cantidad o más recursos que Dragon Age Inquisition, pero muchos jugadores informan que el juego no se ejecuta en él.
uylmz

2
@Reek Dudo que un usuario final pueda decir fácilmente cuán intensivos son los recursos de un juego en particular en comparación con otro.
Gort the Robot

9

Tres hilos en tiempo real que nunca duermen y otro hilo. Si hay menos de cuatro núcleos, el cuarto subproceso nunca se ejecuta. Si el cuarto subproceso necesita comunicarse con uno de los subprocesos en tiempo real para que el subproceso en tiempo real finalice, el código no terminará con menos de cuatro núcleos.

Obviamente, si los subprocesos en tiempo real están esperando algo que no les permite dormir (como un spinlock), el diseñador del programa se equivocó.


1
Posiblemente, cuando una aplicación de usuario solicita subprocesos en tiempo real en primer lugar, el diseñador se equivocó: D
Luaan

2
Lo he hecho. Medio millón de líneas de código. Un caso con aproximadamente 300 líneas. El subproceso en tiempo real pasa la mayor parte del tiempo esperando la entrada para que pueda marcar la entrada y pasarlo a un subproceso de menor prioridad.
Joshua

2
@Luaan Para la mayoría de las aplicaciones, estoy de acuerdo con usted, pero los juegos son una bestia diferente, al igual que las aplicaciones integradas. En ambos casos, la preocupación por jugar bien con otras aplicaciones simultáneas desaparece en favor del rendimiento.
reirab

Si bien no sería particularmente eficiente, este escenario no llevaría a ningún punto muerto: la inversión prioritaria se encargaría de ello (suponiendo que haya un planificador decente a mitad de camino en cualquier sistema operativo principal de la última década)
Voo

2
@Joshua > Windows no sabe qué es la inversión de prioridad. ¿Qué? support.microsoft.com/kb/96418 , msdn.microsoft.com/en-us/library/windows/desktop/ms684831.aspx . Además, inversión de prioridad es el término que describe el problema , no una solución (@Voo).
Bob

3

En primer lugar, los hilos de software no tienen nada que ver con los hilos de hardware y a menudo se mezclan. Los subprocesos de software son piezas de código que pueden enviarse y ejecutarse por sí mismas dentro del contexto del proceso. Los subprocesos de hardware son administrados principalmente por el sistema operativo y se envían al núcleo del procesador cuando se habla de programas regulares. Estos subprocesos de hardware se envían en función de la carga; El despachador de hilos de hardware actúa más o menos como un equilibrador de carga.

Sin embargo, cuando se trata de juegos, especialmente juegos de alta gama, a veces los hilos de hardware son administrados por el juego en sí o el juego le indica al despachador de hilos de hardware qué hacer. Esto se debe a que cada tarea o grupo de tareas no tiene la misma prioridad que en un programa normal. Debido a que Dragon Age proviene de un estudio de juegos de alta gama que usa motores de juegos de alta gama, puedo imaginar que usa un despacho "manual" y luego el número de núcleos se convierte en un requisito mínimo del sistema. Cualquier programa se bloqueará cuando envíe un fragmento de código al tercer núcleo físico que se ejecuta en una máquina con solo 1 o 2 núcleos.


Esta. Recuerde que decir "verificar no de núcleos" significa que una empresa está fabricando su producto de software de una manera específica para obligar a los usuarios a comprar hardware más caro (lo cual sería mal intencionado).
uylmz

2
Estos problemas existen mientras haya juegos de PC. Al principio teníamos 486dx y 486sx, más tarde el Pentium MMX y no MMX, core y non-core y hoy tenemos los requisitos n-core. Esta es una de las razones por las que todavía existen consolas.
dj bazzie wazzie

44
¿Tiene una referencia para los juegos que se hacen cargo de la programación de la CPU? Por lo que yo sabía, esto no es posible directamente en Windows, al menos no de una manera que pueda fallar en la forma que sugieres.
Jules

2
@djbazziewazzie en realidad Windows proporciona una API para hacer exactamente eso, es decir, establecer un hilo para usar siempre el mismo núcleo; Esto se llama afinidad de subprocesos, y no le permite seleccionar manualmente qué código se ejecuta dónde y cuándo, y no puede causar una falla del sistema como sugiere (el sistema ignorará una solicitud para establecer afinidad a un núcleo no existente, y solo sigue programando el subproceso en cualquier núcleo cuando esté disponible. Estoy bastante seguro de que esto es lo que utiliza id Tech, y realmente no equivale a "administrar los subprocesos de hardware en sí".
Julio

1
@djbazziewazzie También parece que malinterpretas el punto de Grand Central Dispatch, que no brinda a los desarrolladores más control sobre cómo su código está programado para un núcleo; de hecho, su propósito es exactamente lo contrario: elegir cuántos hilos crear y qué código debería ejecutarse en cada hilo fuera de las manos de las aplicaciones para que pueda optimizarse para el hardware disponible a nivel de todo el sistema. La dependencia de tener un cierto número de núcleos es exactamente el tipo de problema que GCD fue diseñado para prevenir.
Jules

1

Dado que es posible usar virtualizar para tener más núcleos virtuales que físicos y el software no sabría que se está ejecutando en un virtualizar y, en cambio, pensar que tiene tantos núcleos físicos, diría que dicho software no es posible.

Es decir, no es posible escribir software que siempre se detendrá en menos de N núcleos.

Como otros han señalado, existen soluciones de software que pueden verificar potencialmente, especialmente si el sistema operativo y el código que se usa tienen poca protección contra las condiciones de carrera cuando N procesos se ejecutan en procesadores <N. El verdadero truco es el código que fallará cuando tenga menos de N procesadores, pero no fallará cuando tenga N procesadores pero tenga un sistema operativo que pueda asignar trabajo a menos de N procesadores.


1

Podría ser que hay tres hilos haciendo algo (generando fondos o generando movimiento NPC) y pasando eventos a un cuarto, que se supone que agrega / filtra los eventos y actualiza el modelo de vista. Si el cuarto hilo no recibe todos los eventos (porque no está programado en un núcleo), entonces el modelo de vista no se actualiza correctamente. Esto solo puede suceder esporádicamente, pero esos núcleos deben estar disponibles en cualquier momento. Esto podría explicar por qué no ves un uso elevado de la CPU todo el tiempo, pero el juego no funciona correctamente de todos modos.


1
En tal escenario, el juego también fallaría aleatoriamente cuando los servicios en segundo plano estaban programados para ejecutarse, lo cual es bastante frecuente en la mayoría de las PC.
Jules

1

Creo que Joshua se dirige por el camino correcto, pero no hasta su conclusión.

Suponga que tiene una arquitectura en la que hay tres subprocesos escritos para hacer todo lo posible; cuando terminan lo que están haciendo, lo vuelven a hacer. Para mantener el rendimiento, estos subprocesos no liberan el control de nada, no quieren arriesgarse al retraso del programador de tareas de Windows. Mientras haya 4 o más núcleos, esto funciona bien, fallará si no los hay.

En general, esto sería una mala programación, pero los juegos son otra cuestión: cuando se enfrenta a una elección entre un diseño que es inferior en todo el hardware o un diseño que es superior en un hardware suficientemente bueno o una falla en los desarrolladores de juegos de hardware inferiores, generalmente eligen para requerir el hardware.


Por lo general, no es posible escribir un hilo que no ceda el control a otros hilos. Todos los sistemas operativos modernos que no son RTOS utilizan la multitarea preventiva, lo que intencionalmente hace imposible que un hilo (modo de usuario) no libere el control de un núcleo dado. Los hilos de kernel, por supuesto, son un asunto diferente.
reirab

@reirab Impulsar es prioridad.
Loren Pechtel el

@Loren no cambia el hecho de que el programador todavía muere su trabajo, lo que significa que debe compartir el tiempo con otros subprocesos de la misma prioridad y el planificador aumenta la prioridad de los subprocesos hambrientos. No puedes hacer eso en sistemas operativos normales e incluso si pudieras, los juegos ciertamente tampoco serían una aplicación aceptable para hacerlo.
Voo

1

Is it possible to write code (or complete software, rather than a piece of code) that won't work properly when run on a CPU that has less than N number of cores?

Absolutamente. El uso de subprocesos en tiempo real sería un buen ejemplo de una situación en la que esto no solo es posible, sino la forma deseada (y a menudo, la única forma correcta) de hacer el trabajo. Sin embargo, los subprocesos en tiempo real generalmente se limitan al núcleo del sistema operativo, generalmente para los controladores que deben poder garantizar que un evento de hardware de algún tipo se maneje dentro de un período de tiempo definido. No debe tener subprocesos en tiempo real en aplicaciones de usuario normales y no estoy seguro de que sea posible tener uno en una aplicación de modo de usuario de Windows. En general, los sistemas operativos hacen que sea intencionalmente imposible hacerlo desde la tierra del usuario precisamente porque permite que una aplicación determinada tome el control del sistema.

Con respecto a las aplicaciones de aterrizaje de usuarios: su suposición de que verificar una determinada cantidad de subprocesos para ejecutarse es necesariamente maliciosa en su intención no es correcta. Por ejemplo, podría tener 2 tareas de ejecución prolongada e intensivas en rendimiento que necesitan un núcleo para sí mismas. Independientemente de la velocidad del núcleo de la CPU, compartir un núcleo con otros subprocesos podría ser una degradación del rendimiento grave e inaceptable debido a la alteración del caché junto con las penalizaciones normales incurridas por el cambio de subprocesos (que son bastante sustanciales). En este caso, sería perfectamente razonable, especialmente para un juego, configurar cada uno de estos hilos para que tenga afinidad solo en un núcleo particular para cada uno de ellos y luego configurar todos sus otros hilos para que no tengan afinidad en esos 2 núcleos. Sin embargo, para hacer esto, usted '


1

Cualquier código que use spinlocks con cualquier cantidad notable de contención de bloqueo funcionará terriblemente (hasta un punto donde, para una aplicación como un juego, puede decir "no funciona" ) si el número de hilos excede el número de núcleos.

Imagine, por ejemplo, un hilo productor que envía tareas a una cola que sirve a 4 hilos consumidores. Solo hay dos núcleos:

El productor intenta obtener el spinlock, pero lo tiene un consumidor que se ejecuta en el otro núcleo. Los dos núcleos se ejecutan de manera sincronizada mientras el productor gira, esperando que se libere el bloqueo. Esto ya es malo, pero no tan malo como podría ser.
Desafortunadamente, el hilo del consumidor está al final de su tiempo cuántico, por lo que se adelanta y se programa otro hilo del consumidor. Intenta apoderarse de la cerradura, pero, por supuesto, la cerradura se toma, por lo que ahora dos núcleos giran y esperan algo que no puede suceder.
El subproceso productor llega al final de su intervalo de tiempo y se adelanta, otro consumidor se despierta. Una vez más, dos consumidores están esperando que se libere un bloqueo, y simplemente no sucederá antes de que pasen dos cuánticos más.
[...] Finalmente, el consumidor que sostenía el spinlock ha liberado el bloqueo. Inmediatamente lo toma quien está girando sobre el otro núcleo. Hay un 75% de posibilidades (3 a 1) de que sea otro hilo de consumo. En otras palabras, es 75% probable que el productor todavía esté estancado. Por supuesto, esto significa que los consumidores también se estancan. Sin las tareas de sustitución del productor, no tienen nada que hacer.

Tenga en cuenta que esto funciona en principio con cualquier tipo de bloqueo, no solo spinlocks, sino que el efecto devastador es mucho más destacado con los spinlocks porque la CPU mantiene los ciclos de grabación mientras no logra nada.

Ahora imagine que, además de lo anterior, algún programador tuvo la brillante idea de utilizar un hilo dedicado con afinidad establecida en el primer núcleo, por lo que RDTSC dará resultados confiables en todos los procesadores (de todos modos, no lo hará, pero algunas personas piensan que sí).


Es por eso que los buenos spinlocks degradan a otros tipos de bloqueos después de un corto tiempo, y los mejores lo hacen mucho más rápido si los usos anteriores del mismo bloqueo han tenido que disminuir.
Ian

-1

Si entiendo lo que estás preguntando, es posible, pero es algo muy, muy malo.

El ejemplo canónico de lo que está describiendo sería mantener un contador que se incrementa en múltiples hilos. Esto no requiere casi nada en términos de potencia informática, pero requiere una coordinación cuidadosa entre los hilos. Mientras solo un hilo a la vez haga un incremento (que en realidad es una lectura seguida de una adición seguida de una escritura), su valor siempre será correcto. Esto se debe a que un subproceso siempre leerá el valor "anterior" correcto, agregará uno y escribirá el valor "siguiente" correcto. Obtenga dos hilos en la acción al mismo tiempo y ambos leerán el mismo valor "anterior", obtendrán el mismo resultado del incremento y escribirán el mismo valor "siguiente". El contador se habrá incrementado efectivamente solo una vez, aunque dos hilos piensen que cada uno lo hizo.

Esta dependencia entre el tiempo y la corrección es lo que la informática llama una condición de carrera .

Las condiciones de carrera a menudo se evitan mediante el uso de mecanismos de sincronización para asegurarse de que los subprocesos que desean operar en una parte de datos compartidos tengan que estar en línea para acceder. El contador descrito anteriormente podría usar un bloqueo de lectura-escritura para esto.

Sin acceso al diseño interno de Dragon Age: Inquisition , todo lo que cualquiera puede hacer es especular sobre por qué se comporta de la manera en que lo hace. Pero intentaré basarme en algunas cosas que he visto en mi propia experiencia:

Puede ser que el programa se base en cuatro hilos que se han ajustado para que todo funcione cuando los hilos se ejecutan sin interrupción en sus propios núcleos físicos. El "ajuste" podría venir en la forma de reorganizar el código o insertar durmientes en lugares estratégicos para mitigar los errores inducidos por la condición de la raza que surgieron durante el desarrollo. Nuevamente, todo esto es una conjetura, pero he visto las condiciones de carrera "resueltas" de esa manera más veces de las que me gustaría contar.

Ejecutar un programa como ese en cualquier cosa menos capaz que el entorno para el que se ajustó introduce cambios de tiempo que son el resultado de que el código no se ejecuta tan rápido o, más probablemente, cambios de contexto. Los cambios de contexto ocurren de manera física (es decir, los núcleos físicos de la CPU cambian entre el trabajo que tienen sus núcleos lógicos) y lógico (es decir, el sistema operativo en la CPU está asignando trabajo a los núcleos), pero tampoco es una divergencia significativa de lo que sería el tiempo de ejecución "esperado". Eso puede provocar un mal comportamiento.

Si Dragon Age: Inquisition no da el simple paso de asegurarse de que haya suficientes núcleos físicos disponibles antes de continuar, es culpa de EA. Probablemente estén gastando una pequeña fortuna respondiendo llamadas de soporte y correos electrónicos de personas que intentaron ejecutar el juego con muy poco hardware.


1
Algunos jugadores dicen que es causado por DRM que se ejecuta en 2 núcleos y el juego real también se ejecuta en 2. Cuando DRM y los hilos del juego se ejecutan en el mismo núcleo, se estropea. Pero esto no me parece correcto, puede ser una pequeña historia hecha por un jugador que no sabe mucho sobre arquitectura sw o hw.
uylmz

44
las condiciones de carrera realmente no tienen mucho que ver con el conteo de núcleos, -1 ... una máquina de un solo núcleo con múltiples subprocesos virtuales puede tener condiciones de carrera totalmente dependientes de la técnica de división de tiempo del tiempo de ejecución, o un sistema de muchos núcleos podría evitar todas las condiciones de carrera dependientes sobre cuán estricto es con las operaciones membares ...
Jimmy Hoffa

1
@Reek: Sin un conocimiento profundo de cómo funciona el programa, cualquier cosa es una suposición. Dos núcleos para hacer solo el DRM me parecen un poco excesivos.
Blrfl

1
@ Jimmy Jimmy: No estoy de acuerdo. Una condición de carrera sigue siendo una condición de carrera, incluso cuando no está causando un comportamiento no deseado. El conteo central puede influir en si ese comportamiento ocurre o no, que es lo que preguntó el interrogador, pero no lo cité como la única variable.
Blrfl

-1

Windows tiene una funcionalidad incorporada para esto: la función GetLogicalProcessorInformation está en la API de Windows . Puede llamarlo desde su programa para obtener información sobre núcleos, núcleos virtuales e hyperthreading.

Entonces la respuesta a su pregunta sería: Sí.


3
No estoy preguntando "¿Puedo encontrar ningún núcleo del código?" ... Tal código será mal intencionado (lo obliga a comprar una CPU más costosa para ejecutar un programa, sin la necesidad de potencia computacional).
uylmz

3
Esta función proporciona mucha más información que solo un "número de núcleos" sin procesar. Con esta información puede deducir núcleos físicos, núcleos lógicos y más. Si puede deducir eso, puede escribir software para usar esta información. De una manera buena o mala (programa de bloqueo cuando ve 4 núcleos pero menos de 4 núcleos físicos).
Pieter B

1
Esto puede funcionar en Windows, pero ¿qué pasa con OSX / Linux / iOS / Android / etc.? Si bien se hace referencia a un juego como una instancia donde se ve este comportamiento (y la correlación natural sería Windows = Gaming), no parece ser una solicitud específica del juego.
Robert

Para un juego como Dragon Age, los sistemas en cuestión son Windows / XBox / PS4.
Gort the Robot

Linux tiene /proc/cpuinfoy sysconf(_SC_NPROCESSORS_ONLN)(este último se menciona en POSIX). Sin embargo, usar la información para imponer un umbral de rendimiento mínimo sigue siendo una forma bastante mala.
cHao
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.