Espacios de nombres
Variantes

std::execution::sequenced_policy, std::execution::parallel_policy, std::execution::parallel_unsequenced_policy, std::execution::unsequenced_policy

De cppreference.com
 
 
Biblioteca de algoritmos
Políticas de ejecución (C++17)
Operaciones de secuencia no modificantes
(C++11)(C++11)(C++11)
(C++17)
Operaciones de secuencia modificantes
Operaciones en almacenamiento no inicializado
Operaciones de partición
Operaciones de ordenación
(C++11)
Operaciones de búsqueda binaria
Operaciones de conjuntos (en rangos ordenados)
Operaciones de pila
(C++11)
Operaciones mínimo/máximo
(C++11)
(C++17)
Permutaciones
Operaciones numéricas
Bibliotecas C
 
<tbody> </tbody>
Definido en el archivo de encabezado <execution>
class sequenced_policy { /* sin especificar */ };
(1) (desde C++17)
class parallel_policy { /* sin especificar */ };
(2) (desde C++17)
class parallel_unsequenced_policy { /* sin especificar */ };
(3) (desde C++17)
class unsequenced_policy { /* sin especificar */ };
(4) (desde C++20)
1) El tipo de política de ejecución utilizado como un tipo único para desambiguar la sobrecarga de algoritmos paralelos y requerir que la ejecución de un algoritmo paralelo no puede paralelizarse. Las invocaciones de funciones de acceso a elementos en los algoritmos paralelos invocados con esta política (habitualmente especificada como std::execution::seq) son secuenciadas indeterminadamente en el hilo que llama.
2) El tipo de política de ejecución utilizado como un tipo único para desambiguar la sobrecarga de algoritmos paralelos e indicar que la ejecución de un algoritmo paralelo puede paralelizarse. Se permite que las invocaciones de funciones de acceso a elementos en los algoritmos paralelos invocados con esta política (habitualmente especificada como std::execution::par) se ejecuten en ya sea el hilo que invoca o en un hilo implícitamente creado por la biblioteca para soportar la ejecución de algoritmos paralelos. Tales invocaciones que se ejecutan en el mismo hilo están secuenciadas indeterminadamente entre sí.
3) El tipo de política de ejecución utilizado como un tipo único para desambiguar la sobrecarga de algoritmos paralelos e indicar que la ejecución de un algoritmo paralelo puede ser paralelizada, vectorizada, o migrada a través de hilos (tal como un programador de robo de padres, parent-stealing scheduler). Se permite que las invocaciones de funciones de acceso a elementos en los algoritmos paralelos invocados con esta política se ejecuten de manera no ordenada en hilos no especificados, y están secuenciadas entre sí dentro de cada hilo.
4) El tipo de política de ejecución utilizado como un tipo único para desambiguar la sobrecarga de algoritmos paralelos e indicar que la ejecución de un algoritmo paralelo puede vectorizarse. Por ejemplo, executarse en un solo hilo usando instrucciones que operen en múltiples elementos de datos.

Durante la ejecución de un algoritmo paralelo con cualquiera de estas políticas de ejecución, si la invocación de una función de acceso a un elemento egresa mediante una excepción no atrapada, se llama a std::terminate, pero las implementaciones pueden definir políticas de ejecución adicionales que manejen las excepciones de distinta manera.

Notas

Es la responsibilidad del programador evitar carreras de datos y bloqueos mutuos al usar la política de ejecución paralela:

int a[] = {0,1};
std::vector<int> v;
std::for_each(std::execution::par, std::begin(a), std::end(a), [&](int i) {
  v.push_back(i*2+1); // ERROR: carrera de datos
});
std::atomic<int> x{0};
int a[] = {1,2};
std::for_each(std::execution::par, std::begin(a), std::end(a), [&](int) {
  x.fetch_add(1, std::memory_order_relaxed);
  while (x.load(std::memory_order_relaxed) == 1) { } // ERROR: asume orden de ejecución
});
int x = 0;
std::mutex m;
int a[] = {1,2};
std::for_each(std::execution::par, std::begin(a), std::end(a), [&](int) {
  std::lock_guard<std::mutex> guard(m);
  ++x; // correcto
});

Las políticas de ejecución sin secuenciar son el único caso donde las llamadas a función son sin secuenciar entre sí, lo que significa que pueden intercalarse. En todas las demás situaciones en C++, son secuenciadas indeterminadamente (no pueden intercalarse). Por esa razón, no se permite a los usuarios que asignen o desasignen memoria, adquieran cerrojos de exclusión mutua (mutexes), utilicen especializaciones de std::atomic que no son libres de bloqueo, o en general, llevar a cabo cualquier operación no segura para vectorización al usar estas políticas (las operaciones no seguras para vectorización son aquellas que se sincronizan-con otra función; por ejemplo, std::mutex::unlock se sincroniza-con la próxima llamada a std::mutex::lock).

int x = 0;
std::mutex m;
int a[] = {1,2};
std::for_each(std::execution::par_unseq, std::begin(a), std::end(a), [&](int) {
  std::lock_guard<std::mutex> guard(m); // ERROR: constructor lock_guard llama a m.lock()
  ++x;
});

Si la implementación no puede paralelizar o vectorizar (por ejemplo, debido a una falta de recursos), todas las políticas de ejecución pueden recurrir a la política secuencial.

Véase también

(C++17)(C++17)(C++17)(C++20)
Objetos de políticas de ejecución globales.
(constante) [editar]