Data Communication, Child Task
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.
|
Example
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.
Possible Correction Strategies
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.