Namespaces
Variants

std:: kill_dependency

From cppreference.net
Concurrency support library
Threads
(C++11)
(C++20)
this_thread namespace
(C++11)
(C++11)
Cooperative cancellation
Mutual exclusion
Generic lock management
Condition variables
(C++11)
Semaphores
Latches and Barriers
(C++20)
(C++20)
Futures
(C++11)
(C++11)
(C++11)
Safe reclamation
Hazard pointers
Atomic types
(C++11)
(C++20)
Initialization of atomic types
(C++11) (deprecated in C++20)
(C++11) (deprecated in C++20)
Memory ordering
kill_dependency
(C++11) (deprecated in C++26)
Free functions for atomic operations
Free functions for atomic flags
ヘッダーで定義 <atomic>
template < class T >
T kill_dependency ( T y ) noexcept ;
(C++11以降)
(C++26以降でconstexpr)
(C++26で非推奨)

std::memory_order_consume アトミックロード操作によって開始される依存関係ツリーが std::kill_dependency の戻り値を超えて拡張されないことをコンパイラに通知する。つまり、引数は戻り値に依存性を持ち込まない。

これは、依存関係チェーンが関数スコープを離れる場合(かつ関数が [[ carries_dependency ]] 属性を持たない場合)に、不必要な 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);
}
// 依存チェーンは右側のパラメータを通じてこの関数に入り、
// 関数終了前にkillされます(追加の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内部で開始された依存性チェーンが過度なacquireなしにpへ継続
    do_something_with(g(&c, p->a)); // p->bはキャッシュから取り込まれない
    do_something_with(g(p->a, &c)); // 左引数はcarries_dependency属性を持たない
                                    // メモリacquireフェンスが発行される可能性あり
                                    // p->bはg()が呼び出される前に可視化される
}

関連項目

指定されたアトミック操作に対するメモリ順序制約を定義する
(列挙型)
Cドキュメント for kill_dependency