std:: kill_dependency
|
|
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Определено в заголовочном файле
<atomic>
|
||
|
template
<
class
T
>
T kill_dependency ( T y ) noexcept ; |
(начиная с C++11)
(constexpr начиная с C++26) (устарело в C++26) |
|
|
Сообщает компилятору, что дерево зависимостей, начатое операцией атомарной загрузки
std::memory_order_consume
, не распространяется за пределы возвращаемого значения
Это может использоваться для избежания ненужных барьеров
std::memory_order_acquire
, когда цепочка зависимостей покидает область видимости функции (и функция не имеет атрибута
|
(до C++26) |
|
Просто возвращает y . Этот шаблон функции устарел. |
(начиная с C++26) |
Содержание |
Параметры
| y | - | выражение, возвращаемое значение которого должно быть удалено из дерева зависимостей |
Возвращаемое значение
Возвращает y , больше не являющийся частью дерева зависимостей (до C++26) .
Примеры
file1.cpp:
struct Foo { int* a; int* b; }; std::atomic<Foo*> foo_head[10]; int foo_array[10][10]; // операция consume начинает цепочку зависимостей, которая выходит за пределы этой функции [[carries_dependency]] Foo* f(int i) { return foo_head[i].load(memory_order_consume); } // цепочка зависимостей входит в эту функцию через правый параметр и // уничтожается до завершения функции (так что дополнительная операция acquire не выполняется) int g(int* x, int* y [[carries_dependency]]) { return std::kill_dependency(foo_array[*x][*y]); }
file2.cpp:
[[carries_dependency]] struct Foo* f(int i); int g(int* x, int* y [[carries_dependency]]); int c = 3; void h(int i) { Foo* p; p = f(i); // цепочка зависимостей, начатая внутри f, продолжается в p без избыточного захвата do_something_with(g(&c, p->a)); // p->b не загружается из кэша do_something_with(g(p->a, &c)); // левый аргумент не имеет атрибута carries_dependency // может быть установлен барьер захвата памяти // p->b становится видимым до входа в g() }
Смотрите также
|
(C++11)
|
определяет ограничения упорядочения памяти для данной атомарной операции
(enum) |
|
C documentation
для
kill_dependency
|
|