As far as an implementation of atomics on PPC goes, I recommend starting with 
GCC intrinsics, as these are also supported by IBM XLC. Leave inline assembly 
as an possible optimization later. I doubt it is worth the extra effort in most 
cases. 

If someone wants to work on this, I can try to help with testing and such. I 
have access to both Blue Gene and POWER7 systems right now. I may be able to 
arrange access for Chapel developers if that is critical. 

Jeff

Sent from my iPhone

> On Nov 20, 2013, at 8:57 AM, "Michael P. Ferguson" <[email protected]> 
> wrote:
> 
> Hi Jason -
> 
> Can you explain why the existing atomics interface in
> Atomics.chpl is not sufficient?
> 
> Then, assuming you need some different functionality, why not extend
> the existing atomics implementation instead of creating a completely
> new one? The existing implementation defines functions like
>  atomic_fetch_add_explicit_uint_least64
> in runtime/include/atomics/*/chpl-atomics.h
> 
> For example, to create XLC style Power intrinsics, it would make sense
> to add a new directory there with a different .h file.
> 
> You can call these C functions directly from Chapel, although I could
> believe that you need to change something to get them to do what you
> want. The Atomics module mostly adds an 'on' statement around these calls.
> 
> Cheers,
> 
> -michael
> 
> ________________________________________
> From: Jason Riedy [[email protected]]
> Sent: Tuesday, November 19, 2013 18:50
> To: [email protected]
> Subject: Atomic-intrinsics.chpl sanity check
> 
> [this is a bit of a follow-up to in-person interactions at SC13,
> but posting it here for a wider audience (aka not pestering Brad
> *again*)...]
> 
> Does the following seem like a half-way sane method for adapting
> to different compilers' intrinsics in Chapel?  There's heavy
> cheating around the ll/sc, and I don't have a Power account handy
> for testing, so consider this a sketch...
> 
> 
> // module Atomic-intrinsics.chpl
> use Atomics;
> 
> module impl {
>  use ChapelBase;
>  // XXX: Don't recall if pgi implements these...
>  inline proc gccish_intrinsics() param {
>    return CHPL_TARGET_COMPILER == "gnu" || CHPL_TARGET_COMPILER == "intel" ||
>      CHPL_TARGET_COMPILER == "pgi" || CHPL_TARGET_COMPILER == 
> "cray-prgenv-gnu" ||
>      CHPL_TARGET_COMPILER == "cray-prgenv-intel" ||
>      CHPL_TARGET_COMPILER == "cray-prgenv-pgi";
>  }
>  // XXX: This should be for xlc on power and not other platforms.
>  inline proc xlcish_power_intrinsics() param {
>    return CHPL_TARGET_COMPILER == "xlc";
>  }
>  inline proc xmtish_intrinsics() param {
>    compilerError("Get a real machine.");
>    return false;
>  }
>  inline proc target_compiler_name() param { return CHPL_TARGET_COMPILER; }
> }
> use impl;
> 
> 
> // local{} clauses just to make sure...
> 
> // OP: add
> 
> inline proc atomic_fetch_add(ref x, val: x.type, const 
> order:memory_order=memory_order_seq_cst) : x.type {
>  if (gccish_intrinsics()) {
>    extern proc __atomic_fetch_add(ref x: real(64), val: real(64), 
> order:memory_order) : real(64);
>    extern proc __atomic_fetch_add(ref x: int(64), val: int(64), 
> order:memory_order) : int(64);
>    extern proc __atomic_fetch_add(ref x: uint(64), val: uint(64), 
> order:memory_order) : uint(64);
>    extern proc __atomic_fetch_add(ref x: real(32), val: real(32), 
> order:memory_order) : real(32);
>    extern proc __atomic_fetch_add(ref x: int(32), val: int(32), 
> order:memory_order) : int(32);
>    extern proc __atomic_fetch_add(ref x: uint(32), val: uint(32), 
> order:memory_order) : uint(32);
>    extern proc __atomic_fetch_add(ref x: int(16), val: int(16), 
> order:memory_order) : int(16);
>    extern proc __atomic_fetch_add(ref x: uint(16), val: uint(16), 
> order:memory_order) : uint(16);
>    extern proc __atomic_fetch_add(ref x: int(8), val: int(8), 
> order:memory_order) : int(8);
>    extern proc __atomic_fetch_add(ref x: uint(8), val: uint(8), 
> order:memory_order) : uint(8);
>    inline proc __atomic_fetch_add(x, val, order) {
>      compilerError("No fetch and add for this type.");
>      return 0:x.type;
>    }
> 
>    var retval : x.type;
>    local {
>      retval = __atomic_fetch_add(x, val, order);
>    }
>    return retval;
>  } else if (xlcish_power_intrinsics()) {
>    compilerWarning("Completely untested atomics for ", 
> target_compiler_name());
>    compilerWarning("  Needs isync, eieio, etc. for memory order.");
>    var retval : x.type;
>    inline proc __fa(ref x: int(32), in val: int(32)) {
>      extern proc __fetch_and_add(ref x: int(32), in val: int(32)) : int(32);
>      return __fetch_and_add(x, val);
>    }
>    inline proc __fa(ref x: int(64), in val: int(64)) {
>      extern proc __fetch_and_addlp(ref x: int(64), in val: int(64)) : int(64);
>      return __fetch_and_addlp(x, val);
>    }
>    inline proc __fa(ref x: real(32), in val: real(32)) {
>      extern proc __lwarx(ref x: real(32)) : real(32);
>      extern proc __stwcx(ref x: real(32), in val: real(32)) : int(32);
>      var outval : real(32);
>      var newval : real(32);
>      do {
>        outval = __lwarx(x);
>        newval = outval + val;
>      } while !(__stwcx (x, newval));
>      return outval;
>    }
>    inline proc __fa(ref x: real(64), in val: real(64)) {
>      extern proc __ldarx(ref x: real(64)) : real(64);
>      extern proc __stdcx(ref x: real(64), in val: real(64)) : int(64);
>      var outval : real(64);
>      var newval : real(64);
>      do {
>        outval = __ldarx(x);
>        newval = outval + val;
>      } while !(__stdcx (x, newval));
>      return outval;
>    }
>    inline proc __fa(x, val) {
>      compilerError("No fetch and add for this type.");
>    }
>    local {
>      retval = __fa(x, val);
>    }
>    return retval;
>  } else {
>    compilerError("Unrecognized target compiler: ", target_compiler_name());
>  }
> }
> 
> inline proc atomic_add_fetch(ref x, val: x.type, const 
> order:memory_order=memory_order_seq_cst) : x.type {
>  if (gccish_intrinsics()) {
>    extern proc __atomic_add_fetch(ref x: real(64), val: real(64), 
> order:memory_order) : real(64);
>    extern proc __atomic_add_fetch(ref x: int(64), val: int(64), 
> order:memory_order) : int(64);
>    extern proc __atomic_add_fetch(ref x: uint(64), val: uint(64), 
> order:memory_order) : uint(64);
>    extern proc __atomic_add_fetch(ref x: real(32), val: real(32), 
> order:memory_order) : real(32);
>    extern proc __atomic_add_fetch(ref x: int(32), val: int(32), 
> order:memory_order) : int(32);
>    extern proc __atomic_add_fetch(ref x: uint(32), val: uint(32), 
> order:memory_order) : uint(32);
>    extern proc __atomic_add_fetch(ref x: int(16), val: int(16), 
> order:memory_order) : int(16);
>    extern proc __atomic_add_fetch(ref x: uint(16), val: uint(16), 
> order:memory_order) : uint(16);
>    extern proc __atomic_add_fetch(ref x: int(8), val: int(8), 
> order:memory_order) : int(8);
>    extern proc __atomic_add_fetch(ref x: uint(8), val: uint(8), 
> order:memory_order) : uint(8);
>    inline proc __atomic_add_fetch(x, val, order) {
>      compilerError("No fetch and add for this type.");
>      return 0:x.type;
>    }
> 
>    var retval : x.type;
>    local {
>      retval = __atomic_add_fetch(x, val, order);
>    }
>    return retval;
>  } else if (xlcish_power_intrinsics()) {
>    compilerWarning("Completely untested atomics for ", 
> target_compiler_name());
>    compilerWarning("  Needs isync, eieio, etc. for memory order.");
>    var retval : x.type;
>    inline proc __fa(ref x: int(32), in val: int(32)) {
>      extern proc __fetch_and_add(ref x: int(32), in val: int(32)) : int(32);
>      return __fetch_and_add(x, val) + val;
>    }
>    inline proc __fa(ref x: int(64), in val: int(64)) {
>      extern proc __fetch_and_addlp(ref x: int(64), in val: int(64)) : int(64);
>      return __fetch_and_addlp(x, val) + val;
>    }
>    inline proc __fa(ref x: real(32), in val: real(32)) {
>      extern proc __lwarx(ref x: real(32)) : real(32);
>      extern proc __stwcx(ref x: real(32), in val: real(32)) : int(32);
>      var outval : real(32);
>      var newval : real(32);
>      do {
>        outval = __lwarx(x);
>        newval = outval + val;
>      } while !(__stwcx (x, newval));
>      return newval;
>    }
>    inline proc __fa(ref x: real(64), in val: real(64)) {
>      extern proc __ldarx(ref x: real(64)) : real(64);
>      extern proc __stdcx(ref x: real(64), in val: real(64)) : int(64);
>      var outval : real(64);
>      var newval : real(64);
>      do {
>        outval = __ldarx(x);
>        newval = outval + val;
>      } while !(__stdcx (x, newval));
>      return newval;
>    }
>    inline proc __fa(x, val) {
>      compilerError("No fetch and add for this type.");
>    }
>    local {
>      retval = __fa(x, val);
>    }
>    return retval;
>  } else {
>    compilerError("Unrecognized target compiler: ", target_compiler_name());
>  }
> }
> 
> 
> inline proc atomic_add(ref x, val: x.type, const 
> order:memory_order=memory_order_seq_cst) : x.type {
>  // Sufficient.
>  return atomic_fetch_add(x, val, order);
> }
> 
> --
> Jason Riedy
> 
> 
> ------------------------------------------------------------------------------
> Shape the Mobile Experience: Free Subscription
> Software experts and developers: Be at the forefront of tech innovation.
> Intel(R) Software Adrenaline delivers strategic insight and game-changing
> conversations that shape the rapidly evolving mobile landscape. Sign up now.
> http://pubads.g.doubleclick.net/gampad/clk?id=63431311&iu=/4140/ostg.clktrk
> _______________________________________________
> Chapel-users mailing list
> [email protected]
> https://lists.sourceforge.net/lists/listinfo/chapel-users
> 
> ------------------------------------------------------------------------------
> Shape the Mobile Experience: Free Subscription
> Software experts and developers: Be at the forefront of tech innovation.
> Intel(R) Software Adrenaline delivers strategic insight and game-changing 
> conversations that shape the rapidly evolving mobile landscape. Sign up now. 
> http://pubads.g.doubleclick.net/gampad/clk?id=63431311&iu=/4140/ostg.clktrk
> _______________________________________________
> Chapel-users mailing list
> [email protected]
> https://lists.sourceforge.net/lists/listinfo/chapel-users

------------------------------------------------------------------------------
Shape the Mobile Experience: Free Subscription
Software experts and developers: Be at the forefront of tech innovation.
Intel(R) Software Adrenaline delivers strategic insight and game-changing 
conversations that shape the rapidly evolving mobile landscape. Sign up now. 
http://pubads.g.doubleclick.net/gampad/clk?id=63431311&iu=/4140/ostg.clktrk
_______________________________________________
Chapel-users mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/chapel-users

Reply via email to