異なるタスク (子タスク) が読み取りを行う値に、タスクが書き込みを行った際に発生します。子タスクは別のタスクで入れ子になったタスクです。

ID |
コードの場所 |
説明 |
|---|---|---|
1 |
割り当てサイト |
存在する場合、メモリーブロックが割り当てられた場所と関連するコールスタックを示します。 |
2 |
並列サイト |
データ通信問題を含む並列サイトの位置と関連するコールスタックを示します。 |
3 |
書き込み |
メモリーを書き込んだ命令と関連するコールスタックを示します。 |
4 |
読み取り |
別のタスクの実行でメモリーが読み取られた命令と関連するコールスタックを示します。 |
void problem() {
int* pointer = new int; // サイト割り当て
ANNOTATE_SITE_BEGIN(datacomm_site1); // 並列サイト開始
ANNOTATE_TASK_BEGIN(task1);
*pointer = 999; // 書き込み
ANNOTATE_TASK_END();
assert(*pointer == 999); // 読み取り
ANNOTATE_SITE_END();
}この例では、1 つのタスクがヒープに割り当てられた int に書き込みを行い、別のタスクがその値を読み取っています。
void data_communication() {
ANNOTATE_SITE_BEGIN(data_communication_site); // 並列サイト
{
for (int i=0; i<N; i++) {
ANNOTATE_TASK_BEGIN(data_communication_task1);
{
communication++; /* 子タスクで書き込み */ // 書き込み
}
ANNOTATE_TASK_END();
printf(“%d\n”, communication); /* 親タスクで読み取り */ // 読み取り
}
}
ANNOTATE_SITE_END();
}この例では、インクリメントされる変数は各タスクの後に読み取られます。これによりシリアル依存関係が生じます。
アプリケーションの整合性を保持できる場合は、親タスクでの読み取りを子タスクに移動することを検討してください。上記の例では、そうすることで非決定的な結果になります。読み取りを移動することが困難な場合、ループのパイプライン化など異なる手法を用いる必要があります。