2
votes

I would like to know where do we need to set critical sections?

If there are multiple threads with a shared array, and each one want to write in different place does it need to be in a critical section, even though each thread write to a different place in the array?

lets say that I have 2 dimensional array M[3][3], initial_array[3] and some double variable and I want to calculate something and store it at the first column of M. I can use with a for loop, but I want to use with openMP , so I did:

 omp_set_num_threads(3);
 #pragma omp parallel shared(M,variable)
 {  
     int id = omp_get_thread_num();
     double init = initial_array[id]*variable;
     M[id][0] = init;
 }   

It works fine, but I know that it can cause to deadlock or for bad running time. I mean what if I had more threads and even a larger M.. what is the correct way to set critical section? another thing i want to ask is about the initial_array, is it also need to be shared?

2

2 Answers

2
votes

This is safe code.

Random access in arrays does not cause any race conditions to other elements in the array. As long as you continue to read and write to unshared elements within the array concurrently, you'll never hit a race condition.

Keep in mind that a read can race with a write depending on the type and size of the element. Your example shows double, and I'd be concerned if you had reads concurrent with write operations on the same element. It is possible for there to be a context switch during a write, but that depends on your arch/platform. Anyways, you aren't doing this but it is worth mentioning.

2
votes

I don't see any problem with regards to concurrency since you are accessing different parts of the memory (different indices of the array), but the only problem I see is performance hit if your cores have dedicated L1 caches.

In this case there will be a performance hit due to cache coherency, where one updates the index, invalidates others, does a write back etc. For small no of threads/cores not an issue but on threads running on large number of cores it sure it. Because the data your threads running on aren't truly independent, they are read as a block of data in cache (if you are accessing M[0][0], then not only M[0][0] is read into the cache but M[0][0] to M[n][col] where n depends upon the cache block size ). And if the block is large, it might contain more of shared data.