Visible to Intel only — GUID: GUID-403878BC-FD7C-4C39-80F4-1356F2BF4BBB
Visible to Intel only — GUID: GUID-403878BC-FD7C-4C39-80F4-1356F2BF4BBB
Incidental Sharing
Sharing is incidental when tasks use the same memory location, but do not communicate any information using it.
The Basic Pattern
Suppose that a task always writes to a memory location before reading from it, and that the value that it writes is not read again outside the task. For example:
extern int x; // ... ANNOTATE_SITE_BEGIN(site1); for (i = 0; i != n; ++i) { ANNOTATE_ITERATION_TASK(task1); x = a[i]; b[i] = x * b[i]; } ANNOTATE_SITE_END(site1);
The variable x is both read and written in the task, so there will be a sharing problem when multiple copies of the task execute at the same time. For example:
Task 0 sets x to a[0].
Task 1 sets x to a[1].
Task 0 computes x * b[0].
What is interesting is that the sharing is incidental to the logic of the program. Each iteration of the loop uses x, but its use in each iteration is totally independent. Memory locations used in this way are called privatizable, because giving each task its own private memory location will eliminate the sharing without changing the program behavior.
Memory Allocators
The use of dynamically allocated memory is a special case of incidental sharing. Consider this task:
ANNOTATE_TASK_BEGIN(task2); Type *ptr = allocate_Type(); // some code that uses the object pointed to by ptr free_Type(ptr); ANNOTATE_TASK_END();
If allocate_Type() returns the same address to one task that was used and freed by another task, then those tasks will both access the same memory location, but the sharing is incidental. The memory allocator will never return a pointer to memory that has been allocated and not freed, so the tasks will not use the same dynamically allocated memory location at the same time, and the appearance of sharing is an illusion.
The Dependencies tool understands the standard memory allocators such as C/C++ new/delete and malloc/free, but it does not know about any custom memory allocators that your program might have. If your code has custom memory allocators, you can mark their uses with the special-purpose C/C++ annotations ANNOTATE_RECORD_ALLOCATION and ANNOTATE_RECORD_DEALLOCATION.