Parallel computing — jumbled up output?

后端 未结 2 777
别跟我提以往
别跟我提以往 2020-12-11 05:51

I\'m trying to learn the basics of parallel computing, but I\'m running into an issue on my computer. Take a look at my code below. Basically, I want to print out the line &

2条回答
  •  一个人的身影
    2020-12-11 06:09

    As already explained, the assumption that printf() is atomic and won't mangle your output whereas std::cout::operator<<() is not and will mess things up if fundamentally wrong.

    However, there is still a (tiny) part of "truth" in this, but at a different level. Let me give you an example:

    If I try an OpenMP "Hello world" C-style, that might give this:

    printf( "Hello from thread %d of %d\n",
             omp_get_thread_num(),
             omp_get_num_threads() );
    

    The same one C++-style could look like this:

    std::cout << "Hello from thread " << omp_get_thread_num()
              << " of " << omp_get_num_threads()
              << std::endl;
    

    And the essential difference between the two is that for printf(), I only call the printing method once, with a fully prepared output string, while the C++-style one will call std::cout::operator<<() 5 times, with only bits and pieces of lines that may or may not be sent to the standard output. Internally, anything can happen and I won't try to commit on any sort of behaviour. But at least by using printf() here, I increase my chances of a clean output, even if I cannot guaranty it.

    Here is a full example:

    #include 
    #include 
    #include 
    
    int main() {
        #pragma omp parallel
        printf( "Hello from thread %d of %d with printf()\n",
                 omp_get_thread_num(),
                 omp_get_num_threads() );
    
        printf( "*** outside of parallel region ***\n" );
    
        #pragma omp parallel
        std::cout << "Hello from thread " << omp_get_thread_num()
                  << " of " << omp_get_num_threads()
                  << " with std::cout"
                  << std::endl;
        return 0;
    }
    

    Which on my Linux laptop gives me (GCC 5.2):

    ~/tmp$ g++ -fopenmp stdout.cc
    ~/tmp$ ./a.out 
    Hello from thread 3 of 4 with printf()
    Hello from thread 0 of 4 with printf()
    Hello from thread 2 of 4 with printf()
    Hello from thread 1 of 4 with printf()
    *** outside of parallel region ***
    Hello from thread Hello from thread Hello from thread Hello from thread 1 of 4 with std::cout23 of 4 with std::cout
     of 4 with std::cout
    0 of 4 with std::cout
    
    ~/tmp$
    

    If you look carefully, you can see that none of the individual calls to std::cout::operator<<() is split, but each new call is an opportunity for the various threads to races each-other, and to get the output mangled.

    So again, telling that printf() is atomic and won't mess things up is wrong, but simply, for a complex output string, it is less likely to be mangled than with std::cout.

提交回复
热议问题