Share via


Comparar el runtime de simultaneidad con otros modelos de simultaneidad

En este documento se describen las diferencias entre las características y los modelos de programación del runtime de simultaneidad y otras tecnologías. Al entender las ventajas del runtime de simultaneidad en comparación con las ventajas de otros modelos de programación, puede seleccionar la tecnología que mejor satisfaga los requisitos de las aplicaciones.

Si está usando actualmente otro modelo de programación, como el grupo de subprocesos de Windows u OpenMP, hay situaciones en las que puede ser adecuado migrar al runtime de simultaneidad. Por ejemplo, en el tema Migrar de OpenMP al Runtime de simultaneidad se describe cuándo puede ser adecuado migrar de OpenMP al runtime de simultaneidad. Sin embargo, si está satisfecho con el rendimiento de la aplicación y la compatibilidad de depuración actual, la migración no es necesaria.

Puede usar las características y ventajas de productividad del runtime de simultaneidad para complementar una aplicación existente que usa otro modelo de simultaneidad. El runtime de simultaneidad no puede garantizar el equilibrio de carga cuando varios programadores de tareas compiten por los mismos recursos. Sin embargo, cuando las cargas de trabajo no se superponen, este efecto es mínimo.

Secciones

  • Comparación de la programación preferente con la programación cooperativa

  • Comparación del runtime de simultaneidad con la API de Windows

  • Comparación del runtime de simultaneidad con OpenMP

Comparación de la programación preferente con la programación cooperativa

El modelo de programación preferente y el modelo de programación cooperativa son dos formas comunes de habilitar varias tareas para compartir recursos de computación, como procesadores o subprocesos de hardware.

Programación preferente y cooperativa

La programación preferente es un mecanismo de operación por turnos basado en prioridades que da a cada tarea acceso exclusivo a un recurso de computación durante un período de tiempo determinado y, a continuación, pasa a otra tarea. Este tipo de programación se suele usar en sistemas operativos multitarea, como Windows. La programación cooperativa es un mecanismo que proporciona a cada tarea acceso exclusivo a un recurso de computación hasta que la tarea finaliza o hasta que cede su acceso al recurso. El Runtime de simultaneidad utiliza la programación cooperativa junto con el programador preferente del sistema operativo para optimizar el uso de los recursos de procesamiento.

Diferencias entre los programadores preferentes y cooperativos

Los programadores preferentes buscan dar a varios subprocesos el mismo acceso a los recursos de computación para asegurarse de que cada subproceso progrese. En los equipos con muchos recursos de computación, garantizar un acceso equitativo se vuelve menos problemático; sin embargo, garantizar el uso eficaz de los recursos pasa a ser más problemático.

Un programador preferente en modo kernel requiere que el código de la aplicación se base en el sistema operativo para tomar las decisiones de programación. A la inversa, un programador cooperativo en modo usuario permite que el código de la aplicación tome sus propias decisiones de programación. Dado que la programación cooperativa permite que un gran número de las decisiones de programación las tome la aplicación, se reduce en gran medida la sobrecarga asociada a la sincronización en modo kernel. Normalmente, un programador cooperativo pasa las decisiones de programación al kernel del sistema operativo cuando no tiene que programar ningún otro trabajo. Asimismo, las pasa al programador del sistema operativo cuando hay una operación de bloqueo que se ha comunicado al kernel pero no al programador en modo usuario. En los sistemas operativos que admiten subprocesos programables en modo usuario, el programador del Runtime de simultaneidad convierte estas operaciones de bloqueo en operaciones de bloqueo cooperativas.

Programación cooperativa y eficacia

Para un programador preferente, todas las tareas con el mismo nivel de prioridad son iguales. Un programador preferente suele programar los subprocesos por orden de creación. Además, un programador preferente asigna por turnos un intervalo de tiempo a cada subproceso en función de la prioridad de los subprocesos. Si bien este mecanismo aporta equidad (cada subproceso progresa), esto va en detrimento de la eficacia. Por ejemplo, muchos algoritmos de cálculo intensivo no requieren equidad. Lo que necesitan es que las tareas relacionadas finalicen con la mayor brevedad. La programación cooperativa permite a una aplicación programar el trabajo de manera más eficaz. Por ejemplo, consideremos el caso de una aplicación con muchos subprocesos. La programación de subprocesos que no comparten recursos para la ejecución simultánea puede reducir la sobrecarga de sincronización y, por tanto, aumentar la eficacia. Otra manera eficaz de programar tareas consiste en ejecutar canalizaciones de tareas (donde cada tarea actúa sobre el resultado de la tarea anterior) en el mismo procesador de modo que la entrada de cada fase de la canalización ya esté cargada en la memoria caché.

Usar conjuntamente la programación preferente y la programación cooperativa

La programación cooperativa no resuelve todos los problemas de programación. Por ejemplo, las tareas que no ceden de manera equitativa ante otras tareas pueden llegar a consumir todos los recursos de computación disponibles y evitar que otras tareas progresen. El Runtime de simultaneidad utiliza las ventajas en términos de eficacia que aporta la programación cooperativa para complementar las garantías de equidad de la programación preferente. De manera predeterminada, el Runtime de simultaneidad proporciona un programador cooperativo que usa un algoritmo de robo de trabajo para distribuir el trabajo eficazmente entre los recursos de computación. Sin embargo, el programador del Runtime de simultaneidad también se basa en el programador preferente del sistema operativo para distribuir los recursos de manera equitativa entre las aplicaciones. Se pueden crear asimismo programadores personalizados y directivas de programador en las aplicaciones para obtener un control específico sobre la ejecución de los subprocesos.

[Ir al principio]

Comparación del runtime de simultaneidad con la API de Windows

La interfaz de programación de aplicaciones Microsoft Windows, a la que se suele hacer referencia con el término API de Windows (anteriormente Win32), proporciona un modelo de programación que habilita la simultaneidad en las aplicaciones. El Runtime de simultaneidad se fundamenta en la API de Windows para proporcionar modelos de programación adicionales que no están disponibles en el sistema operativo subyacente.

El Runtime de simultaneidad se basa en el modelo de subprocesos de la API de Windows para realizar trabajos en paralelo. También utiliza la administración de memoria de la API de Windows y los mecanismos de almacenamiento local de subprocesos. En Windows 7 y Windows Server 2008 R2, utiliza la compatibilidad con la API de Windows para los subprocesos programables por el usuario y los equipos con más de 64 subprocesos de hardware. El Runtime de simultaneidad extiende el modelo de la API de Windows, ya que proporciona un programador de tareas cooperativo y un algoritmo de robo de trabajo para optimizar el uso de los recursos de computación, además de habilitar varias instancias simultáneas del programador.

Para obtener más información sobre la API de Windows, vea Información general de la API de Windows.

Lenguajes de programación

La API de Windows utiliza el lenguaje de programación C para exponer el modelo de programación. El Runtime de simultaneidad proporciona una interfaz de programación C++ que aprovecha las últimas características del lenguaje C++. Por ejemplo, las funciones lambda proporcionan un mecanismo sucinto y con seguridad de tipos para definir las funciones de trabajo paralelo. Para obtener más información sobre las nuevas características de C++ que el Runtime de simultaneidad utiliza, vea Información general sobre el runtime de simultaneidad.

Subprocesos y grupos de subprocesos

El mecanismo de simultaneidad central en la API de Windows es el subproceso. Normalmente, se utiliza la función CreateThread para crear subprocesos. Si bien los subprocesos son relativamente fáciles de crear y utilizar, el sistema operativo asigna una cantidad significativa de tiempo y otros recursos a su administración. Además, aunque queda garantizado que cada subproceso dispone del mismo tiempo de ejecución que cualquier otro subproceso con el mismo nivel de prioridad, la sobrecarga asociada requiere la creación de tareas suficientemente grandes. Para tareas pequeñas o más específicas, la sobrecarga asociada a la simultaneidad puede pesar más que la ventaja de ejecutar las tareas en paralelo.

Los grupos de subprocesos son una forma de reducir el costo de la administración de subprocesos. Los grupos de subprocesos personalizados y la implementación de grupo de subprocesos que proporcionada la API de Windows permiten que los elementos de trabajo de tamaño reducido se ejecuten eficazmente en paralelo. El grupo de subprocesos de Windows mantiene los elementos de trabajo en una cola FIFO (PEPS, primero en entrar, primero en salir). Cada elemento de trabajo se inicia según el orden en que se agregó al grupo.

El Runtime de simultaneidad implementa un algoritmo de robo de trabajo para extender el mecanismo de programación FIFO. El algoritmo mueve las tareas que aún no se han iniciado a los subprocesos que se están quedando sin elementos de trabajo. Si bien el algoritmo de robo de trabajo puede equilibrar las cargas de trabajo, también puede dar lugar a que los elementos de trabajo se vuelvan a ordenar. Este proceso de reordenación puede hacer que un elemento de trabajo se inicie en un orden diferente del orden en que se envió. Esto resulta útil en el caso de los algoritmos recursivos, donde hay mayor probabilidad de que los datos sean compartidos por tareas nuevas que por tareas antiguas. Lograr que los nuevos elementos se ejecuten en primer lugar significa un número menor de líneas no ejecutadas en caché y posiblemente menos errores de página.

Desde la perspectiva del sistema operativo, el robo de trabajo no es equitativo. No obstante, cuando una aplicación implementa un algoritmo o una tarea para que se ejecute en paralelo, no siempre importa la equidad entre las subtareas. Lo que sí importa es la velocidad con la que finaliza la tarea global. Para otros algoritmos, FIFO es la estrategia de programación adecuada.

Comportamiento en los distintos sistemas operativos

En Windows XP y Windows Vista, las aplicaciones que usan el Runtime de simultaneidad se comportan de manera similar, aunque el rendimiento del montón mejora en Windows Vista.

En Windows 7 y Windows Server 2008 R2, el sistema operativo admite además la simultaneidad y la escalabilidad. Por ejemplo, estos sistemas operativos son compatibles con equipos que tienen más de 64 subprocesos de hardware. Es preciso modificar una aplicación existente que utiliza la API de Windows para que pueda aprovechar estas nuevas características. Sin embargo, una aplicación que usa el Runtime de simultaneidad emplea automáticamente estas características y no requiere ningún tipo de modificación.

Tanto Windows 7 como Windows Server 2008 R2 agregan compatibilidad con los subprocesos programables en modo usuario (UMS). Estos subprocesos permiten que los programadores en modo usuario y el kernel funcionen de manera más eficaz. Si bien UMS no abandona el modelo de preferencia, aumenta la eficacia, ya que permite a las aplicaciones y bibliotecas realizar una programación cooperativa sin transiciones del kernel. Además, devuelve el control a la aplicación cuando hay un subproceso bloqueado en el kernel, de modo que la aplicación pueda realizar trabajo adicional durante el intervalo de tiempo restante. El Runtime de simultaneidad utiliza la programación UMS cuando el sistema operativo la admite. Para obtener más información sobre UMS, vea Programación en modo usuario.

[Ir al principio]

Comparación del runtime de simultaneidad con OpenMP

El Runtime de simultaneidad habilita diversos modelos de programación. Estos modelos pueden superponerse a los modelos de otras bibliotecas o complementarlos. En esta sección, se compara el runtime de simultaneidad con OpenMP.

El modelo de programación OpenMP se define como un estándar abierto y está claramente vinculado a los lenguajes de programación Fortran y C/C++. Las versiones 2.0 y 2.5 de OpenMP son apropiadas para los algoritmos de procesamiento paralelo que son iterativos; es decir, realizan una iteración en paralelo en una matriz de datos. OpenMP es más eficaz cuando el grado de paralelismo está predeterminado y coincide con los recursos disponibles en el sistema. El modelo OpenMP se presta especialmente para la computación de alto rendimiento, en la que se distribuyen problemas de computación muy grandes entre los recursos de procesamiento de un solo equipo. En este escenario, el entorno de hardware es conocido y el desarrollador puede esperar tener acceso exclusivo a los recursos de computación cuando se ejecuta el algoritmo.

Sin embargo, otros entornos de computación menos restringidos pueden no ser apropiados para OpenMP. Por ejemplo, los problemas recursivos, como el algoritmo de ordenación rápida (quicksort) o las búsquedas en un árbol de datos, son más difíciles de implementar mediante OpenMP. El runtime de simultaneidad complementa las capacidades de OpenMP al proporcionar la Biblioteca de modelos de procesamiento paralelo (PPL) y la Biblioteca de agentes asincrónicos. A diferencia de OpenMP, el Runtime de simultaneidad proporciona un programador dinámico que se adapta a los recursos disponibles y ajusta el grado de paralelismo en función de las cargas de trabajo.

Muchas de las características del Runtime de simultaneidad se pueden extender. Además, se pueden combinar las características existentes para crear nuevas características. Dado que OpenMP se basa en las directivas de compilador, no se puede extender con facilidad.

Para obtener más información sobre la comparación del runtime de simultaneidad con OpenMP y cómo migrar el código existente de OpenMP para usar el runtime de simultaneidad, vea Migrar de OpenMP al Runtime de simultaneidad.

[Ir al principio]

Vea también

Referencia

Información general de la API de Windows

Conceptos

Runtime de simultaneidad

Información general sobre el runtime de simultaneidad

Parallel Patterns Library (PPL)

Biblioteca de agentes asincrónicos

Otros recursos

OpenMP in Visual C++

Historial de cambios

Fecha

Historial

Motivo

Julio de 2010

Información adicional sobre la migración e interoperabilidad.

Mejora de la información.