* GNAT 4.8 atomic access to 64-bit objects @ 2013-11-14 15:57 Dmitry A. Kazakov 2013-11-14 20:34 ` Ludovic Brenta 2013-11-15 19:08 ` Stefan.Lucks 0 siblings, 2 replies; 10+ messages in thread From: Dmitry A. Kazakov @ 2013-11-14 15:57 UTC (permalink / raw) The following does not compile anymore for 32-bit Linux targets, e.g. under Debian: procedure Test is type T is mod 2**64; X : T; pragma Atomic (X); -- Error begin null; end Test; The above seems no more legal, because the compiler does not support atomic access to X. Is there a way to change this without machine code insertions? -- Regards, Dmitry A. Kazakov http://www.dmitry-kazakov.de ^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: GNAT 4.8 atomic access to 64-bit objects 2013-11-14 15:57 GNAT 4.8 atomic access to 64-bit objects Dmitry A. Kazakov @ 2013-11-14 20:34 ` Ludovic Brenta 2013-11-15 8:44 ` Dmitry A. Kazakov 2013-11-15 19:08 ` Stefan.Lucks 1 sibling, 1 reply; 10+ messages in thread From: Ludovic Brenta @ 2013-11-14 20:34 UTC (permalink / raw) "Dmitry A. Kazakov" <mailbox@dmitry-kazakov.de> writes: > The following does not compile anymore for 32-bit Linux targets, e.g. under > Debian: > > procedure Test is > type T is mod 2**64; > X : T; > pragma Atomic (X); -- Error > begin > null; > end Test; > > The above seems no more legal, because the compiler does not support > atomic access to X. > > Is there a way to change this without machine code insertions? Even with machine code insertions, I fail to see how a 32-bit processor can accept 64-bit integers as atomic. I'd suggest you use 64-bit floating-point registers instead; i386 processors have them, I think. That has been a useful trick for a decade or so :) -- Ludovic Brenta. ^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: GNAT 4.8 atomic access to 64-bit objects 2013-11-14 20:34 ` Ludovic Brenta @ 2013-11-15 8:44 ` Dmitry A. Kazakov 2013-11-15 19:25 ` Georg Bauhaus 0 siblings, 1 reply; 10+ messages in thread From: Dmitry A. Kazakov @ 2013-11-15 8:44 UTC (permalink / raw) On Thu, 14 Nov 2013 21:34:26 +0100, Ludovic Brenta wrote: > "Dmitry A. Kazakov" <mailbox@dmitry-kazakov.de> writes: >> The following does not compile anymore for 32-bit Linux targets, e.g. under >> Debian: >> >> procedure Test is >> type T is mod 2**64; >> X : T; >> pragma Atomic (X); -- Error >> begin >> null; >> end Test; >> >> The above seems no more legal, because the compiler does not support >> atomic access to X. >> >> Is there a way to change this without machine code insertions? > > Even with machine code insertions, I fail to see how a 32-bit processor > can accept 64-bit integers as atomic. movq ? (the target is not an i386) > I'd suggest you use 64-bit floating-point registers instead; i386 > processors have them, I think. That has been a useful trick for a > decade or so :) Using unchecked union or unchecked conversion? -- Regards, Dmitry A. Kazakov http://www.dmitry-kazakov.de ^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: GNAT 4.8 atomic access to 64-bit objects 2013-11-15 8:44 ` Dmitry A. Kazakov @ 2013-11-15 19:25 ` Georg Bauhaus 2013-11-15 21:33 ` Dmitry A. Kazakov 0 siblings, 1 reply; 10+ messages in thread From: Georg Bauhaus @ 2013-11-15 19:25 UTC (permalink / raw) On 15.11.13 09:44, Dmitry A. Kazakov wrote: > On Thu, 14 Nov 2013 21:34:26 +0100, Ludovic Brenta wrote: >> I'd suggest you use 64-bit floating-point registers instead; i386 >> processors have them, I think. That has been a useful trick for a >> decade or so :) > > Using unchecked union or unchecked conversion? FTR, a different 32 bit implementation (Ada 95) does not support a binary modulus of 64, and also, while Unchecked_Conversion passes the value 42 from an integer register to a FPT register and back as 42, idly trying type Fake is new Long_Float; pragma Atomic (Fake); gives LRM:C.6(10), Indivisible read/update not supported for given subtype, pragma Atomic ignored ^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: GNAT 4.8 atomic access to 64-bit objects 2013-11-15 19:25 ` Georg Bauhaus @ 2013-11-15 21:33 ` Dmitry A. Kazakov 2013-11-16 10:08 ` Georg Bauhaus 0 siblings, 1 reply; 10+ messages in thread From: Dmitry A. Kazakov @ 2013-11-15 21:33 UTC (permalink / raw) On Fri, 15 Nov 2013 20:25:28 +0100, Georg Bauhaus wrote: > On 15.11.13 09:44, Dmitry A. Kazakov wrote: >> On Thu, 14 Nov 2013 21:34:26 +0100, Ludovic Brenta wrote: > >>> I'd suggest you use 64-bit floating-point registers instead; i386 >>> processors have them, I think. That has been a useful trick for a >>> decade or so :) >> >> Using unchecked union or unchecked conversion? > > FTR, a different 32 bit implementation (Ada 95) does not support a binary > modulus of 64, and also, while Unchecked_Conversion passes the value 42 > from an integer register to a FPT register and back as 42, idly trying > type Fake is new Long_Float; > pragma Atomic (Fake); > gives > LRM:C.6(10), Indivisible read/update not supported for given subtype, pragma Atomic ignored Try this: with Interfaces; with Ada.Unchecked_Conversion; with Ada.Text_IO; procedure Test is type T is mod 2**64; type Atomic_T is new Interfaces.IEEE_Float_64; function Load is new Ada.Unchecked_Conversion (Atomic_T, T); function Store is new Ada.Unchecked_Conversion (T, Atomic_T); X : Atomic_T; pragma Atomic (X); begin X := Store (123); Ada.Text_IO.Put_Line (T'Image (Load (X))); X := Store (Load (X) + 1); Ada.Text_IO.Put_Line (T'Image (Load (X))); end Test; The code generated looks horrific. -- Regards, Dmitry A. Kazakov http://www.dmitry-kazakov.de ^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: GNAT 4.8 atomic access to 64-bit objects 2013-11-15 21:33 ` Dmitry A. Kazakov @ 2013-11-16 10:08 ` Georg Bauhaus 2013-11-16 12:02 ` Dmitry A. Kazakov 0 siblings, 1 reply; 10+ messages in thread From: Georg Bauhaus @ 2013-11-16 10:08 UTC (permalink / raw) On 15.11.13 22:33, Dmitry A. Kazakov wrote: > Try this: > > with Interfaces; > with Ada.Unchecked_Conversion; > with Ada.Text_IO; > > procedure Test is > type T is mod 2**64; > type Atomic_T is new Interfaces.IEEE_Float_64; > ... > end Test; > > The code generated looks horrific. > Maybe according to http://stackoverflow.com/questions/15843159/are-32-bit-software-builds-typically-64-bit-optimized simply wanting movq is not "mode compatible"; however, if there are MMX registers in the CPU you are targetting, the following may be a valid way to get movq nevertheless, albeit using a 64 bit signedinteger. The program was translated in 32 bit GNU/Linux, using GNAT GPL 2012. It uses compiler intrinsics in ways adapted from GNAT.SSE. with Ada.Text_IO; with GNAT.SSE; procedure Atoms is use GNAT.SSE; type m64 is array (0 .. 0) of Integer64; for m64'Alignment use 8; pragma Machine_Attribute (m64, "vector_type"); pragma Machine_Attribute (m64, "may_alias"); function ia32_psllq (Left : m64; Right : m64) return m64; pragma Import (Intrinsic, ia32_psllq, "__builtin_ia32_psllq"); X : Integer64; F : m64; for X'Address use F'Address; begin X := 123; F := ia32_psllq (F, m64'(0 => 1)); Ada.Text_IO.Put_Line (Integer64'Image (X)); -- 246 end Atoms; ^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: GNAT 4.8 atomic access to 64-bit objects 2013-11-16 10:08 ` Georg Bauhaus @ 2013-11-16 12:02 ` Dmitry A. Kazakov 0 siblings, 0 replies; 10+ messages in thread From: Dmitry A. Kazakov @ 2013-11-16 12:02 UTC (permalink / raw) On Sat, 16 Nov 2013 11:08:00 +0100, Georg Bauhaus wrote: > On 15.11.13 22:33, Dmitry A. Kazakov wrote: > >> Try this: >> >> with Interfaces; >> with Ada.Unchecked_Conversion; >> with Ada.Text_IO; >> >> procedure Test is >> type T is mod 2**64; >> type Atomic_T is new Interfaces.IEEE_Float_64; >> ... >> end Test; >> >> The code generated looks horrific. > > Maybe according to > http://stackoverflow.com/questions/15843159/are-32-bit-software-builds-typically-64-bit-optimized > simply wanting movq is not "mode compatible"; however, > if there are MMX registers in the CPU you are targetting, > the following may be a valid way to get movq nevertheless, > albeit using a 64 bit signedinteger. > The program was translated in 32 bit GNU/Linux, using GNAT GPL 2012. > It uses compiler intrinsics in ways adapted from GNAT.SSE. > > with Ada.Text_IO; > with GNAT.SSE; > > procedure Atoms is > use GNAT.SSE; > > type m64 is array (0 .. 0) of Integer64; > for m64'Alignment use 8; > pragma Machine_Attribute (m64, "vector_type"); > pragma Machine_Attribute (m64, "may_alias"); > > function ia32_psllq (Left : m64; Right : m64) return m64; > pragma Import (Intrinsic, ia32_psllq, "__builtin_ia32_psllq"); > > X : Integer64; > F : m64; > for X'Address use F'Address; > begin > X := 123; > F := ia32_psllq (F, m64'(0 => 1)); > Ada.Text_IO.Put_Line (Integer64'Image (X)); -- 246 > end Atoms; With the -mmmx switch, it indeed uses movq in order to load the register. In the test example I wrote, atomic load becomes; movq psllq movq to another location (through Unchecked_Conversion) Atomic store is the reverse. Surprisingly (at least to me), this is about ten times faster than using the floating point trick. I.e. Load + Increment + Store using psllq needs 16ns, using IEEE 64 it does 168ns, on i7-2700K 3.5GHz It would be nice to get rid of psllq, which is a waste. -- Regards, Dmitry A. Kazakov http://www.dmitry-kazakov.de ^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: GNAT 4.8 atomic access to 64-bit objects 2013-11-14 15:57 GNAT 4.8 atomic access to 64-bit objects Dmitry A. Kazakov 2013-11-14 20:34 ` Ludovic Brenta @ 2013-11-15 19:08 ` Stefan.Lucks 2013-11-15 21:19 ` Dmitry A. Kazakov 1 sibling, 1 reply; 10+ messages in thread From: Stefan.Lucks @ 2013-11-15 19:08 UTC (permalink / raw) [-- Attachment #1: Type: TEXT/PLAIN, Size: 419 bytes --] On Thu, 14 Nov 2013, Dmitry A. Kazakov wrote: > Is there a way to change this without machine code insertions? I guess, putting your 64-bit object into a protected object is not an option? ------ I love the taste of Cryptanalysis in the morning! ------ <http://www.uni-weimar.de/cms/medien/mediensicherheit/home.html> --Stefan.Lucks (at) uni-weimar.de, Bauhaus-Universität Weimar, Germany-- ^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: GNAT 4.8 atomic access to 64-bit objects 2013-11-15 19:08 ` Stefan.Lucks @ 2013-11-15 21:19 ` Dmitry A. Kazakov 2013-11-22 0:30 ` Randy Brukardt 0 siblings, 1 reply; 10+ messages in thread From: Dmitry A. Kazakov @ 2013-11-15 21:19 UTC (permalink / raw) On Fri, 15 Nov 2013 20:08:54 +0100, Stefan.Lucks@uni-weimar.de wrote: > On Thu, 14 Nov 2013, Dmitry A. Kazakov wrote: > >> Is there a way to change this without machine code insertions? > > I guess, putting your 64-bit object into a protected object is not an > option? It is supposed to be lock-free. Using protected object would be very last resort [*]. I was considering: procedure Load ( Ptr : in out T; Ret : in out T; Model : int := ATOMIC_RELAXED ); pragma Import (Intrinsic, Load, "__atomic_load"); The problem with this is that GNAT's implementation of intrinsic import seems incapable to deal with overloaded GCC built-ins. Unfortunately, all __atomic_* built-ins are sort of templates. -------------------------- * I wonder why RM does not mandate pragma Atomic always legal. After all, the compiler could always implement it using a hidden protected object. Except when access occurs on the context of a protected action. Which is statically known (or else program is erroneous). Within a protected action it already atomic. -- Regards, Dmitry A. Kazakov http://www.dmitry-kazakov.de ^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: GNAT 4.8 atomic access to 64-bit objects 2013-11-15 21:19 ` Dmitry A. Kazakov @ 2013-11-22 0:30 ` Randy Brukardt 0 siblings, 0 replies; 10+ messages in thread From: Randy Brukardt @ 2013-11-22 0:30 UTC (permalink / raw) "Dmitry A. Kazakov" <mailbox@dmitry-kazakov.de> wrote in message news:h7hi7m1nbl7e.14h9bnbgzis5a$.dlg@40tude.net... ... > * I wonder why RM does not mandate pragma Atomic always legal. After all, > the compiler could always implement it using a hidden protected object. > Except when access occurs on the context of a protected action. Which is > statically known (or else program is erroneous). Within a protected action > it already atomic. No, it's not statically known what happens in a protected action, since the body of a protected subprogram can call other subprograms (protected or not) in other packages, and those other package bodies need not even exist when the protected subprogram is compiled. (And in any case, Ada does not require any inlining, implicit or otherwise.) Randy. ^ permalink raw reply [flat|nested] 10+ messages in thread
end of thread, other threads:[~2013-11-22 0:30 UTC | newest] Thread overview: 10+ messages (download: mbox.gz / follow: Atom feed) -- links below jump to the message on this page -- 2013-11-14 15:57 GNAT 4.8 atomic access to 64-bit objects Dmitry A. Kazakov 2013-11-14 20:34 ` Ludovic Brenta 2013-11-15 8:44 ` Dmitry A. Kazakov 2013-11-15 19:25 ` Georg Bauhaus 2013-11-15 21:33 ` Dmitry A. Kazakov 2013-11-16 10:08 ` Georg Bauhaus 2013-11-16 12:02 ` Dmitry A. Kazakov 2013-11-15 19:08 ` Stefan.Lucks 2013-11-15 21:19 ` Dmitry A. Kazakov 2013-11-22 0:30 ` Randy Brukardt
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox