Re: C++11 atomics in Mozilla

2013-01-28 Thread Ehsan Akhgari

On 2013-01-28 12:48 AM, Brian Smith wrote:

Joshua Cranmer wrote:

In bug 732043, I want to add a mozilla::Atomic class
that lets us use C++11 atomics where available and fallback to
compiler intrinsics where C++11 atomics are not implemented
(which amounts to gcc 4.4 and Visual Studio 2010 or earlier).


How far are we from Visual Studio 2012 being the default/minimum compiler?


There are currently no plans to do that in the near future to the best 
of my knowledge.


Cheers,
Ehsan
___
dev-platform mailing list
dev-platform@lists.mozilla.org
https://lists.mozilla.org/listinfo/dev-platform


Re: C++11 atomics in Mozilla

2013-01-27 Thread Brian Smith
Joshua Cranmer wrote:
> On 1/27/2013 11:48 PM, Brian Smith wrote:
> > FWIW, in cases like this, I would rather we just use the C++11 API
> > directly even if it means dropping support for common but
> > out-of-date compilers like gcc 4.4 and VS2010.
> 
> I personally prefer an API style where the memory ordering
> constraints of a variable are part of the type declaration as
> opposed to an optional parameter on the access methods
> (which means operator overloading will only ever give you
> sequentially consistent).

OK, I didn't realize you were proposing the new API as a permanent 
replacement/wrapper of the C++11 API.  If the Mozilla Coding Style Guide is 
going to discourage the use of the C++11 API permanently anyway even after all 
supported compilers provide it, then it doesn't really matter how the 
Mozilla-specific API is implemented.

Cheers,
Brian
___
dev-platform mailing list
dev-platform@lists.mozilla.org
https://lists.mozilla.org/listinfo/dev-platform


Re: C++11 atomics in Mozilla

2013-01-27 Thread Joshua Cranmer

On 1/27/2013 11:48 PM, Brian Smith wrote:

Joshua Cranmer wrote:

In bug 732043, I want to add a mozilla::Atomic class
that lets us use C++11 atomics where available and fallback to
compiler intrinsics where C++11 atomics are not implemented
(which amounts to gcc 4.4 and Visual Studio 2010 or earlier).

How far are we from Visual Studio 2012 being the default/minimum compiler?

FWIW, in cases like this, I would rather we just use the C++11 API directly 
even if it means dropping support for common but out-of-date compilers like gcc 
4.4 and VS2010.


I personally prefer an API style where the memory ordering constraints 
of a variable are part of the type declaration as opposed to an optional 
parameter on the access methods (which means operator overloading will 
only ever give you sequentially consistent).

Also, why can't we just implement the C++11 atomic APIs using VS2010's 
intrinsics ourselves, if we know we will need to support VS2010 for a long time?
I have code somewhere that adds a VS2010 intrinsics implementation, but 
I haven't tested it to see if it compiles on VS2010. It's just not been 
high-enough priority for me to finish off the patch and push it into the 
tree.

___
dev-platform mailing list
dev-platform@lists.mozilla.org
https://lists.mozilla.org/listinfo/dev-platform


Re: C++11 atomics in Mozilla

2013-01-27 Thread Brian Smith
Joshua Cranmer wrote:
> In bug 732043, I want to add a mozilla::Atomic class
> that lets us use C++11 atomics where available and fallback to
> compiler intrinsics where C++11 atomics are not implemented
> (which amounts to gcc 4.4 and Visual Studio 2010 or earlier).

How far are we from Visual Studio 2012 being the default/minimum compiler?

FWIW, in cases like this, I would rather we just use the C++11 API directly 
even if it means dropping support for common but out-of-date compilers like gcc 
4.4 and VS2010.

Also, why can't we just implement the C++11 atomic APIs using VS2010's 
intrinsics ourselves, if we know we will need to support VS2010 for a long time?

Cheers,
Brian
___
dev-platform mailing list
dev-platform@lists.mozilla.org
https://lists.mozilla.org/listinfo/dev-platform


Re: C++11 atomics in Mozilla

2012-12-13 Thread Boris Zbarsky

On 12/14/12 1:48 AM, Justin Lebar wrote:

FWIW, I once tried changing all of our atomic string refcounting to
non-atomic operations and could not eke out a performance (or
stability) difference on x64.  This was despite the fact that I was
able to generate profiles where the atomic string refcounting showed
up as taking a few percentage points.  I think bz reproduced this
somewhat surprising result more recently.


What I found was that changing the refcounting on nsStringBuffer to not 
be atomic didn't obviously help.  Neither did inlining those 
addref/release calls (they're out-of-line right now).  But doing both 
together _did_ help a good bit, for my microbenchmark.  Also x64 for 
that test.  And _very_ microbenchmarky...


-Boris
___
dev-platform mailing list
dev-platform@lists.mozilla.org
https://lists.mozilla.org/listinfo/dev-platform


Re: C++11 atomics in Mozilla

2012-12-13 Thread Justin Lebar
> Is code like this safe in the C++1 Unordered model?
> Thread 1:
>   int x = obj->v;
>   obj->Release();
> Thread 2:
>   obj->Release();
> where obj's destructor trashes obj->v.
> The potential hazard is if thread 1's obj->Release() atomic decrement is
> reordered to run before the obj->v load has completed, then Thread 2's
> obj->Release() runs and trashes obj->v, and thread 1 reads the trashed
> value.

Indeed, but note that you don't need a full barrier on release; a
barrier which prevents instructions from being moved down below the
release is sufficient.

(The general rule is that you can move an instruction into a critical
section, but not out of one.)

> For what it's worth, I think asking programmers to even think about such
> question is insane, so I'd go for full memory barriers and sequential
> consistency until we have benchmark numbers showing big wins from other
> choices.

I totally agree, but I think it /might/ be sane to make addref unordered and
release a partial barrier as described above.

FWIW, I once tried changing all of our atomic string refcounting to
non-atomic operations and could not eke out a performance (or
stability) difference on x64.  This was despite the fact that I was
able to generate profiles where the atomic string refcounting showed
up as taking a few percentage points.  I think bz reproduced this
somewhat surprising result more recently.

Of course that says nothing about ARM, or about our other atomic
addrefs.  And really, I still don't entirely believe the correctness
of my result in those tests.

-Justin
___
dev-platform mailing list
dev-platform@lists.mozilla.org
https://lists.mozilla.org/listinfo/dev-platform


Re: C++11 atomics in Mozilla

2012-12-13 Thread Robert O'Callahan
On Fri, Dec 14, 2012 at 12:33 PM, Joshua Cranmer wrote:

> 3. Similar to #2, the ideal version of a reference counter would be
> mozilla::Atomic (which would make threadsafe
> refcounting cheaper on our ARM platforms if we compiled with gcc 4.6 or
> clang 3.1 or newer). However, I'm not sure that no one has written code
> that relies on atomic operations having memory ordering properties, and I
> don't want to go through and audit every thread-safe XPCOM class.
>

Is code like this safe in the C++1 Unordered model?
Thread 1:
  int x = obj->v;
  obj->Release();
Thread 2:
  obj->Release();
where obj's destructor trashes obj->v.
The potential hazard is if thread 1's obj->Release() atomic decrement is
reordered to run before the obj->v load has completed, then Thread 2's
obj->Release() runs and trashes obj->v, and thread 1 reads the trashed
value.

For what it's worth, I think asking programmers to even think about such
question is insane, so I'd go for full memory barriers and sequential
consistency until we have benchmark numbers showing big wins from other
choices.

Rob
-- 
Jesus called them together and said, “You know that the rulers of the
Gentiles lord it over them, and their high officials exercise authority
over them. Not so with you. Instead, whoever wants to become great among
you must be your servant, and whoever wants to be first must be your
slave — just
as the Son of Man did not come to be served, but to serve, and to give his
life as a ransom for many.” [Matthew 20:25-28]
___
dev-platform mailing list
dev-platform@lists.mozilla.org
https://lists.mozilla.org/listinfo/dev-platform


C++11 atomics in Mozilla

2012-12-13 Thread Joshua Cranmer
As you may or may not be aware, one of the goodies that comes in C++11 
is the introduction of an explicit memory model as well as proper 
support for multithreaded code. One important piece of this is 
std::atomic, which provides an interoperable way to do (potentially 
lockless) atomic operations and, under the new memory model, is the only 
safe way to handle multithreaded accesses when not protected by locks 
(if you use volatile to do this right now, your code is broken and you 
don't know it yet). In bug 732043, I want to add a mozilla::Atomic class 
that lets us use C++11 atomics where available and fallback to compiler 
intrinsics where C++11 atomics are not implemented (which amounts to gcc 
4.4 and Visual Studio 2010 or earlier). What would this give us?


1. Atomic operations on non-32-bit types. Well, not all platforms 
support all atomic read-modify-write operations on all word sizes (ARM 
doesn't have 64-bit atomic primitives; Windows only provides a subset of 
operations on 8-bit/16-bit words), but we'd have more coverage than just 
atomic increment/decrement/store on 32-bit words.
2. Compare-and-swap, particularly on pointer variables. An atomic 
compare-and-swap primitive is probably the most important in terms of 
practically implementing high-throughput lock-free concurrent data 
structures.
3. Weaker memory ordering. Current compiler intrinsics--as used in 
PR_ATOMIC_INCREMENT and friends--require full memory barriers around 
every access. For things like reference counters, we can get away with 
not needing memory barriers if the architecture (e.g., ARM) supports it. 
Note that this does require as a prerequisite compilers that speak newer 
atomic intrinsics (Clang 3.1, MSVC 2012, and gcc 4.6 are the min 
versions here).


The problems are the following:
1. Not all architectures support all lock-free atomic operations on all 
sizes of integers; in particular, ARM cannot do atomic operations on 
64-bit variables. A compiler that supports C++11 atomics would fallback 
to locking-based algorithms here, but as I want to put this in MFBT, I 
don't have usable lock dependencies. And I'm not keen on hand-writing 
locking algorithms based on primitives either. :-) My proposed solution 
to this dilemma is to forbid use of mozilla::Atomic if sizeof(T) > 
sizeof(uintptr_t) [rationale being that all architectures should be able 
to support at least lock-free atomic operations on pointers].


2. The API I'm proposing in this instance would not allow you to use an 
atomic operation on a "regular" variable, which is a big difference from 
the current APIs provided by pratom.h. The rationale here is that this 
is much less prone to danger (all accesses to a variable are atomic), as 
well as simplifying APIs. The biggest user of PR_ATOMIC_INCREMENT right 
now is for threadsafe XPCOM refcounting; to move to the new API, we 
would have to restructure the nsISupports helper macros by providing an 
NS_DECL_ISUPPORTS_THREADSAFE macro, although we would be able to lose 
all the NS_IMPL_THREADSAFE_* variants.


3. Similar to #2, the ideal version of a reference counter would be 
mozilla::Atomic (which would make 
threadsafe refcounting cheaper on our ARM platforms if we compiled with 
gcc 4.6 or clang 3.1 or newer). However, I'm not sure that no one has 
written code that relies on atomic operations having memory ordering 
properties, and I don't want to go through and audit every thread-safe 
XPCOM class.


4. Also, in a similar problem to the above, what should the default 
consistence be for mozilla::Atomic? C++11 opts to default to 
sequentially-consistent, but right now, most of our uses of atomic 
macros are for counter variables, which tend to want to be unordered.


5. A last technical point: there is one case in which a C++11 atomics 
class can have a non-atomic access to a variable. The 
value-initialization constructor of std::atomic does not store the value 
atomically. This may seem crazy, but I believe that the primary purpose 
is to be able to declare static-storage variables with initial values 
and not require adding a global initializer. Since I think this is a 
useful feature, I've been considering copying these semantics over, 
although I do admit that it does appear arbitrary and incongruous.



What are your opinions? Or other 
thoughts/questions/flames/comments/concerns?

___
dev-platform mailing list
dev-platform@lists.mozilla.org
https://lists.mozilla.org/listinfo/dev-platform