Boost logo

Boost :

From: William Kempf (sirwillard_at_[hidden])
Date: 2000-08-31 13:46:01


--- In boost_at_[hidden], "Bill Wade" <bill.wade_at_s...> wrote:
> > From: William Kempf [mailto:sirwillard_at_m...]
>
> > --- In boost_at_[hidden], "Bill Wade" <bill.wade_at_s...> wrote:
>
> > > I'm not sure I know how to do a safe read with just
> > > InterlockedExchange.
>
> > int b = a; // according to what you posted, this is atomic
>
> Right. On win32 'a' is read atomically and 'b' hasn't yet been
shared.
>
> > InterlockedExchange(&b, a); // equivalent to above
>
> True. In particular if a plain old read is not atomic the second
version
> doesn't atomically read a value from a. The second argument to
> InterlockedExchange is passed by value, so
>
> c = InterlockedExchange(&b,a);
>
> is semantically equivalent to
>
> tmp = a;
>
> Lock(&b);
> swap(tmp,b);
> Unlock(&b);
>
> c = tmp;
>
> > Regardless, I don't *think* you'll find a performance
> > difference with this and InterlockedExchange. It surely won't be
a
> > 3x difference.
>
> The output from the following program on my machine (just one
thread) is
> 200
> 541
> so it is just a 2.705x difference, with loop overhead thrown in.
>
> #include <iostream>
> #include <time.h>
> #include <vector>
> #include <windows.h>
>
> using namespace std;
>
> int main()
> {
> const int size = 10000000;
>
> vector<long> v(size);
>
> long i;
> long* base = &v[0];
> long sum = 0;
>
> // Get a time for plain old read.
> clock_t t = clock();
> for(i = 0; i < size; ++i)
> sum += base[i];
> t = clock() - t;
> cout << t << endl;
>
> // Get a time for the "identical" code using interlocked exchange
> long temp;
> t = clock();
> for(i = 0; i < size; ++i)
> sum += (InterlockedExchange(&temp, base[i]), temp);
> t = clock() - t;
> cout << t <<endl;
>
> return sum;
> }

The two loops aren't really equivalent since a temporary had to be
used. Removing the temporary with the following code results in an
overhead of only ~2.07x. Granted, there's still overhead. I'm not
at all sure that any of this applies to the discussion of a portable
atomic_t though.

   t = clock();
   for(i = 0; i < size; ++i)
     sum += InterlockedExchange(&base[i], base[i]);
   t = clock() - t;
   std::cout << t << std::endl;

Bill Kempf


Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk