Parallel computing — jumbled up output?

后端 未结 2 762
别跟我提以往
别跟我提以往 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 <iostream>
    #include <stdio.h>
    #include <omp.h>
    
    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.

    0 讨论(0)
  • 2020-12-11 06:15

    Sorry, your professor's mistaken. You need to leverage mutual exclusion or some other barriers in order to guarantee uninterrupted use of a shared resource (which in this case is the STDOUT output file).

    Mixed output is potential expected behavior regardless of printf or std::cout::operator<<(). The differences in behavior you see are subtle differences in the execution duration of each, due to their differing design. You should expect this behavior in either case.

    I just don't understand why it would be working for everyone else.

    It's not. Be a hero to your class and explain how it works and how to fix it. Tell them SO sends their love. :)

    0 讨论(0)
提交回复
热议问题