Skip to main content

PWR006: Avoid privatization of read-only variables

Issue

Read-only variables should be shared instead of private to reduce memory consumption and unnecessary data copying.

Actions

Set the scope of the read-only variable to shared.

Relevance

Since a read-only variable is never written to, it can be safely shared without any risk of race conditions. Sharing variables is more efficient than privatizing them from a memory perspective so it should be favored whenever possible.

Code example

C

In the following code, arrays A and B are never written to. However, they are privatized and thus each thread will hold a copy of each array, effectively using more memory and taking more time to create private copies:

#define SIZE 5

void example() {
int A[SIZE] = {1, 2, 3, 4, 5};
int B[SIZE] = {5, 4, 3, 2, 1};
int sum[SIZE];

#pragma omp parallel for shared(sum) firstprivate(A, B) private(i)
for (int i = 0; i < SIZE; i++) {
sum[i] = A[i] + B[i];
}
}

To save memory, change their scope to shared. This may also prevent memory issues when using arrays, as codes may easily run out of memory for a high number of threads:

#define SIZE 5

void example() {
int A[SIZE] = {1, 2, 3, 4, 5};
int B[SIZE] = {5, 4, 3, 2, 1};
int sum[SIZE];

#pragma omp parallel for shared(sum, A, B) private(i)
for (int i = 0; i < SIZE; i++) {
sum[i] = A[i] + B[i];
}
}

Fortran

In the following code, arrays A and B are never written to. However, they are privatized and thus each thread will hold a copy of each array, effectively using more memory and taking more time to create private copies:

subroutine example()
implicit none
integer :: i
integer :: a(5) = [1, 2, 3, 4, 5]
integer :: b(5) = [6, 7, 8, 9, 10]
integer :: sum(5)

!$omp parallel do default(none) firstprivate(a, b) shared(sum) private(i)
do i = 1, 5
sum(i) = a(i) + b(i)
end do
!$omp end parallel do
end subroutine example

To save memory, change their scope to shared. This may also prevent memory issues when using arrays, as codes may easily run out of memory for a high number of threads:

subroutine example()
implicit none
integer :: i
integer :: a(5) = [1, 2, 3, 4, 5]
integer :: b(5) = [6, 7, 8, 9, 10]
integer :: sum(5)

!$omp parallel do default(none) shared(a, b, sum) private(i)
do i = 1, 5
sum(i) = a(i) + b(i)
end do
!$omp end parallel do
end subroutine example

References