comp.lang.ada
 help / color / mirror / Atom feed
* 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