OpenMP: parallel op and errno at once?

82 Views Asked by At

While omp_thread_num is maintained for a full iteration, the same underlying thread won't necessarily perform the execution.

This made me wonder how omp deals non omp thread locals, i.e. __thread int; or errno, which are thread local to the underlying thread.

I can't find the information in the doc, but it seems like

#pragma omp parallel for
for (int i = 0; i < 10000; ++i) {
    // exec by omp thread 1, using underlying thread a
    fileptr = fopen(filenames[i], "rb");   
    variable_heavy_op(); // or just yield, or nothing, 

    // exec by omp thread 1, using underlying thread b, 
    if (!fileptr)  // local to omp thread 1
        perror(filename[i]);  //  // uses errno, local to underlying thread b, 
}

would risk a really painful to debug rare threading error.

errno is a catastrophic design choice, I know, but some crap is difficult to avoid. Another example would be reading the result of a try lock operation in pthreads, or using omp with any non omp threading primitives or derived libraries like the standard template library.

The question is, is my assertion correct. Or simplified. If i create a __thread variable ( non omp thread bound variable) how does that interact with the omp threadpool?

2

There are 2 best solutions below

4
midjji On BEST ANSWER

Openmp does not guarantee that one omp thread corresponds to one system/os thread, but it does on linux.(pthread)

openmp does not guarantee that one os thread performs an entire operation, but it should on linux as a consequence of the os openmp 2 os thread correspondence. ( This contradicts my previous assertion in the question).

__thread corresponds to threadprivate on linux for gcc, but not for icc, though there is a compat flag. The clang openmp is based on the intel one, but its unclear how it behaves, lack of warning on tests indicate it works like gcc or lacks the warning intel would give. Works like gcc seems likely.

To answer the question directly errno works on linux with gcc if its implemented as thread local, but as homer points out its likely that someone fixed it for common configurations like linux + ICC.

14
Homer512 On

There seems to be a lot going on in this question with some potential misunderstandings of how OpenMP-based threading works. Specifically, I don't see a way of how the thread executing fopen can differ from the one executing perror since both are in the same loop iteration.

However, just to clear some air about the relation of thread number and thread-local variable, note this excerpt from the OpenMP standard:

The values of data in the threadprivate variables of threads that are not initial threads are guaranteed to persist between two consecutive active parallel regions only if all of the following conditions hold:

  • Neither parallel region is nested inside another explicit parallel region;
  • The number of threads used to execute both parallel regions is the same;
  • The thread affinity policies used to execute both parallel regions are the same;
  • The value of the dyn-var internal control variable in the enclosing task region is false at entry to both parallel regions; and
  • No teams construct that is not nested inside of a target construct is encountered between both parallel regions.
  • Neither the omp_pause_resource nor omp_pause_resource_all routine is called.

If these conditions all hold, and if a threadprivate variable is referenced in both regions, then threads with the same thread number in their respective regions will reference the same copy of that variable.

In other words: Under normal circumstances, the same underlying thread with the same thread-local variables serves the same OpenMP thread number across all parallel sections