2012-02-20 18 views
12

He estado pensando en std::async y cómo uno debería usarlo en la futura implementación del compilador. Sin embargo, en este momento estoy un poco atrapado con algo que se siente como un defecto de diseño.std :: async: ¿uso dependiente de la implementación?

El std::async depende de la implementación, probablemente con dos variantes de launch::async, una que inicia la tarea en un nuevo hilo y otro que usa un grupo de hilos/programador de tareas.

Sin embargo, dependiendo de cuál de estas variantes se utilice para implementar std::async, el uso podría variar mucho.

Para la variante basada en "pool de hilos", podría iniciar muchas tareas pequeñas sin preocuparse demasiado por los gastos generales, sin embargo, ¿qué ocurre si una de las tareas se bloquea en algún momento?

Por otro lado, una variante de "abrir un nuevo hilo" no tendría problemas con las tareas de bloqueo, por otro lado, la sobrecarga de ejecutar y ejecutar tareas sería muy alta.

hilos de la piscina: + baja sobrecarga, -nunca jamás bloquear

lanzamiento nuevo hilo: + bien con bloques, -alta sobrecarga

Así que, básicamente, en función de la aplicación, la forma en que usamos std::async sería muy cuidadoso. Si tenemos un programa que funciona bien con un compilador, podría funcionar de manera horrible en otro.

¿Esto es por diseño? ¿O me estoy perdiendo algo? ¿Considerarías esto, como lo hago, como un gran problema?

En la especificación actual me falta algo así como std::oversubscribe(bool) para permitir la implementación en uso dependiente de std::async.

EDITAR: Hasta donde he leído, el documento estándar C++ 11 no da ninguna pista con respecto a si las tareas enviadas a std::async pueden bloquear o no.

+0

Solo como una adición: http://en.cppreference.com/w/cpp/thread/async proporciona un ejemplo bastante simple y realista de bloqueo de llamadas 'std :: async'. – KillianDS

+0

Parece que asume que los grupos de subprocesos tienen un tamaño fijo. En la práctica, muchos tienen un tamaño dinámico, por lo que el bloqueo no es un problema. –

+0

@MooingDuck: ni TBB ni Concrt tienen grupos de subprocesos de tamaño "dinámico". ¿Qué grupos de hilos conoces que tengan un tamaño dinámico? E incluso si tienes un grupo de subprocesos de tamaño dinámico, en cambio, obtienes el problema de la sobresuscripción y la sobrecarga de cualquier heurística necesaria para realizar un seguimiento de cuándo agregar nuevos subprocesos y eliminar los antiguos. – ronag

Respuesta

11

std::async ejecutar las tareas con una política de std::launch::async ejecutar "como en un nuevo hilo", por lo que las agrupaciones de subprocesos realmente no son compatibles --- el tiempo de ejecución tendría que desmontar y volver a crear todas las variables locales de subprocesos ejecución de tareas, que no es sencillo.

Esto también significa que puede esperar que las tareas iniciadas con una política de std::launch::async se ejecuten simultáneamente.Puede haber un retraso en la puesta en marcha, y habrá conmutación de tareas si tiene más subprocesos en ejecución que procesadores, pero deberían estar en ejecución y no en punto muerto solo porque uno espera a esperar otro.

Una implementación puede optar por ofrecer una extensión que permite que sus tareas se ejecuten en un grupo de subprocesos, en cuyo caso depende de esa implementación documentar la semántica.

+1

+1, para "como en un nuevo subproceso" y variables locales de subproceso. – ronag

+0

La asincrónica de MSVC usa un subproceso de subprocesos. Me imagino que cuando un hilo completa una "tarea", informa que se completó, luego restablece su hilo local y luego espera una nueva tarea. Esto significa que el código de usuario nunca tiene que esperar el restablecimiento local de la secuencia. –

+0

No conozco los detalles de la implementación de MSVC, sin embargo, el estándar requiere que las variables 'thread_local' se destruyan antes de que el' future' esté listo. –

1

Espero que las implementaciones ejecuten nuevos subprocesos y dejen el grupo de subprocesos a una versión futura de C++ que lo estandarice. ¿Hay implementaciones que usan un grupo de subprocesos?


MSVC initally utilizó un grupo de subprocesos en función de su tiempo de ejecución concurrente. De acuerdo con STL Fixes In VS 2015, Part 2 esto ha sido eliminado. La especificación C++ dejó algo de espacio para que los implementadores puedan hacer cosas inteligentes, sin embargo, no creo que deje suficiente espacio para esta implementación de agrupación de subprocesos. En particular, creo que la especificación aún requería que los objetos thread_local se destruyeran y se reconstruyeran, pero que la agrupación de subprocesos con ConcRT no habría sido compatible.

+1

Si recuerdo correctamente Microsoft anunció durante la conferencia Going Native 2012 que 'std :: async' usaría Concrt. No sé qué planes tienen gcc y clang. – ronag

+0

MSVC usa un threadpool en este punto, ni libC++ ni libstdC++ usan pools la última vez que lo verifiqué. –

Cuestiones relacionadas