para imagenes imagen emplea ejemplo definicion como atributos atributo agregar c++ multithreading c++11 memory-model carries-dependency

c++ - imagenes - en html, el atributo alt se emplea para



¿Qué significa el atributo[[carries_dependency]]? (2)

En resumen, creo que si hay un atributo de carry_dependency, el código generado para una función debería optimizarse para un caso, cuando el argumento real realmente vendrá del otro hilo y conllevará una dependencia. Del mismo modo para un valor de retorno. Puede haber una falta del rendimiento si esa suposición no es cierta (por ejemplo, en el programa de un solo hilo). Pero también la ausencia de [[carries_dependency]] puede dar como resultado un mal rendimiento en el caso opuesto ... No deberían producirse otros efectos, sino la alteración del rendimiento.

Por ejemplo, la operación de desreferencia del puntero depende de cómo se obtuvo previamente el puntero, y si el valor del puntero p proviene de otro hilo (por operación "consumir") el valor previamente asignado por ese otro hilo a * p se toma en cuenta y visible. Puede haber otro puntero q que sea igual a p (q == p), pero como su valor no proviene de ese otro hilo, el valor de * q puede verse diferente del * p. En realidad * q puede provocar una especie de "comportamiento indefinido" (porque la ubicación de la memoria de acceso está fuera de coordinación con el otro hilo que hizo la asignación).

Realmente, parece que hay un gran error en la funcionalidad de la memoria (y la mente) en ciertos casos de ingeniería ....> :-)

¿Alguien puede explicarlo en un idioma que los simples mortales entienden?


[[carries_dependency]] se usa para permitir que las dependencias se lleven a través de llamadas a funciones. Esto potencialmente permite que el compilador genere un mejor código cuando se usa con std::memory_order_consume para transferir valores entre hilos en plataformas con arquitecturas débilmente ordenadas como la arquitectura POWER de IBM.

En particular, si un valor leído con memory_order_consume se pasa a una función, entonces sin [[carries_dependency]] , entonces el compilador puede tener que emitir una instrucción de valla de memoria para garantizar que se mantenga la semántica de ordenamiento de memoria apropiada. Si el parámetro está anotado con [[carries_dependency]] entonces el compilador puede suponer que el cuerpo de la función transportará correctamente la dependencia, y esta valla ya no es necesaria.

De manera similar, si una función devuelve un valor cargado con memory_order_consume , o derivado de tal valor, entonces sin [[carries_dependency]] se puede requerir que el compilador inserte una instrucción de valla para garantizar que se [[carries_dependency]] la semántica de ordenamiento de memoria apropiada. Con la anotación [[carries_dependency]] , esta valla ya no es necesaria, ya que la persona que llama ahora es responsable de mantener el árbol de dependencias.

p.ej

void print(int * val) { std::cout<<*p<<std::endl; } void print2(int * [[carries_dependency]] val) { std::cout<<*p<<std::endl; } std::atomic<int*> p; int* local=p.load(std::memory_order_consume); if(local) std::cout<<*local<<std::endl; // 1 if(local) print(local); // 2 if(local) print2(local); // 3

En la línea (1), la dependencia es explícita, por lo que el compilador sabe que local se desreferencia, y que debe garantizar que la cadena de dependencia se preserve para evitar una valla en POWER.

En la línea (2), la definición de print es opaca (suponiendo que no está en línea), por lo que el compilador debe emitir una cerca para garantizar que la lectura *p en la print devuelva el valor correcto.

En la línea (3), el compilador puede suponer que aunque print2 también es opaco, la dependencia del parámetro con el valor desreferenciado se conserva en la secuencia de instrucciones y no se necesita ninguna delimitación en POWER. Obviamente, la definición de print2 debe preservar esta dependencia, por lo que el atributo también afectará el código generado para print2 .