* 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-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 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: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 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-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