Intel® Advisor Help
Occurs when a task writes a value that a different (child) task reads. A child task is a task nested inside another task.
ID |
Code Location |
Description |
---|---|---|
1 |
Allocation site |
If present, represents the location and associated call stack when the memory block was allocated. |
2 |
Parallel site |
Represents the location and associated call stack of the parallel site containing the Data Communication problem. |
3 |
Write |
Represents the instruction and associated call stack where the memory was written. |
4 |
Read |
Represents the instruction and associated call stack where the memory was read in a different task execution. |
void problem() { int* pointer = new int; // Allocation site ANNOTATE_SITE_BEGIN(datacomm_site1); // Begin parallel site ANNOTATE_TASK_BEGIN(task1); *pointer = 999; // Write ANNOTATE_TASK_END(); assert(*pointer == 999); // Read ANNOTATE_SITE_END(); }
In this example, one task writes a heap-allocated int, then an ancestor task reads it.
void data_communication() { ANNOTATE_SITE_BEGIN(data_communication_site); // Parallel site { for (int i=0; i<N; i++) { ANNOTATE_TASK_BEGIN(data_communication_task1); { communication++; /* write in child */ // Write } ANNOTATE_TASK_END(); printf(“%d\n”, communication); /* read in parent */ // Read } ANNOTATE_SITE_END(); }
In this example, the incremented variable is read after each task. This creates a serial dependence.
If you can preserve the application's integrity, consider moving the reads by the parent task into the child task. In the example above, this would result in non-deterministic output. If moving the read is not possible, you may need to use a different strategy, such as pipelining the loop.