[C++0x] a better <future>

Jonathan Wakely jwakely.gcc@gmail.com
Sat Jun 20 21:40:00 GMT 2009


2009/6/18 Jonathan Wakely:
> 2009/6/18 Benjamin Kosnik:
>> FYI please put the tests you are using to make these kinds of decisions
>> into testsuite/peformance. Assuming you were testing on linux?
>
> Yes, I will do some performance comparisons on some other arch's using
> the gcc compile farm, but the performance difference on linux was
> significant (2.5 times slower) so I gave up on the atomic version.  I
> assume the reason is that linux mutexes and condvars are already very
> well-tuned whereas the <cstdatomic> code is less mature.
> The performance test was quite artificial: several threads constantly
> polling a future for readiness to intentionally create contention,
> then one thread setting the value, but I'll tidy it up for inclusion.
> Testing any other parts of the interface would only test the
> performance of waiting on a condvar, copying the result, or throwing
> exceptions, so I only tested the performance of is_ready() and
> set_value().

I've attached a test as described above, which I plan to check in to
testsuite/performance/, and in fact for that simple test on linux  the
version using an atomic_address is faster than the version using a
mutex lock, but I think for now it's safer to rely on the <mutex> code
rather than <cstdatomic>.

I have a more complicated test using several promises at once, but not
really suitable to check in, which is where I see the 2.5 times
slowdown using atomic_address.  Cachegrind shows order of magnitude
more L1 cache reads in the atomic_address version.  I plan to
investigate further at a later date.

I'll do the check in tomorrow.

Jonathan
-------------- next part --------------
// Copyright (C) 2009 Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library.  This library is free
// software; you can redistribute it and/or modify it under the
// terms of the GNU General Public License as published by the
// Free Software Foundation; either version 3, or (at your option)
// any later version.

// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.

// You should have received a copy of the GNU General Public License along
// with this library; see the file COPYING3.  If not see
// <http://www.gnu.org/licenses/>.


#include <future>
#include <thread>
#include <testsuite_performance.h>

void poll(std::shared_future<void> f)
{
  while (!f.is_ready())
  { }
}

int main()
{
  using namespace __gnu_test;
  time_counter time;
  resource_counter resource;

  const int n = 20;
  std::promise<void> p;
  std::shared_future<void> f = p.get_future();
  std::thread pollers[n];
  for (int i=0; i < n; ++i)
    pollers[i] = std::thread(poll, f);

  start_counters(time, resource);

  for (int i = 0; i < 1000000; ++i)
    (void)f.is_ready();
  p.set_value();

  for (int i=0; i < n; ++i)
    pollers[i].join();

  stop_counters(time, resource);
  report_performance(__FILE__, "", time, resource);

  return 0;
}


More information about the Libstdc++ mailing list