title: C++ async vs OpenMP tasks
body: <p><strong>In OpenMP</strong>, I can create a bunch of tasks as follows and run them asynchronously using some fixed number of threads:</p>
  
  <pre><code>#pragma omp parallel
  {
     #pragma omp single 
     {
        for (int i = 0; i &lt; 1000; i++) {
           #pragma omp task
           f(i);
  }  }  }
  </code></pre>
  
  <p><strong>In C++11</strong>, I can do something <em>not-quite-same</em> <code>std::async</code>:</p>
  
  <pre><code>std::vector&lt;std::future&gt; futures;
  for (int i = 0; i &lt; 1000; i++) {
     auto fut = std::async(f, i);
     futures.push_back(std::move(fut));
  }
  ...
  for (auto &amp; fut : futures) {
    auto res = fut.get();
    // do something with res
  }
  </code></pre>
  
  <p>What I worry about is efficiency. If I am correct, <strong>in OpenMP</strong>, tasks are stored in some task pool and then distributed to threads (automatically by the OpenMP runtime).</p>
  
  <p><strong>In C++</strong>, at the moment of invoking <code>std::async</code>, the runtime decides whether to run <code>f(i)</code> asynchronously in a new thread or defer its run to the point of invoking <code>std::future::get</code>.</p>
  
  <p>Consequently, either a runtime </p>
  
  <ol>
  <li>creates 1000 threads and run them all concurrently,</li>
  <li>or create less threads, but then some invocation of <code>f(i)</code> will be performed sequentially in the main thread (within the final loop).</li>
  </ol>
  
  <p>Both these options seem to be generally less efficient than what OpenMP does (create many tasks and run them concurrently in a fixed number of threads).</p>
  
  <p>Is there any way to get the same behavior as what OpenMP tasks provide with C++ threading?</p>
  
  <p><strong>UPDATE</strong></p>
  
  <p>I did some measurements with the following code: <a href="https://wandbox.org/permlink/gLCFPr1IjTofxwQh" rel="noreferrer">https://wandbox.org/permlink/gLCFPr1IjTofxwQh</a> on 12C Xeon E5 CPU compiled with GCC 7.2 and <code>-O2</code>:</p>
  
  <ol>
  <li>OpenMP runtime with 12 threads: 12.2 [s]</li>
  <li>C++ threading runtime: 12.4 [s]</li>
  </ol>
  
  <p>(averages from serveral runs). They seem to be practically the same.</p>
  
  <p>However, I also tried the same with 500,000 tasks (<code>n</code>) and 1,000 iterations within them (<code>m</code>) and the times then differed significantly:</p>
  
  <ol>
  <li>OpenMP runtime with 12 threads: 15.1 [s]</li>
  <li>C++ threding runtime: 175.6 [s]</li>
  </ol>
  
  <p><strong>UPDATE 2</strong></p>
  
  <p>I measured <strong>how many times a new thread was created</strong> (following this answer to interpose <code>pthread_create</code> calls: <a href="https://stackoverflow.com/a/3709027/580083">https://stackoverflow.com/a/3709027/580083</a>):</p>
  
  <p>First experiment (20,000 tasks, 20,000 iterations within):</p>
  
  <ol>
  <li>OpenMP runtime with 12 threads: <strong>11</strong></li>
  <li>C++ threding runtime: <strong>20,000</strong></li>
  </ol>
  
  <p>Second experiment (500,000 tasks, 1,000 iterations within):</p>
  
  <ol>
  <li>OpenMP runtime with 12 threads: <strong>11</strong></li>
  <li>C++ threding runtime: <strong>32,744</strong></li>
  </ol>