comp.lang.ada
 help / color / mirror / Atom feed
* Compute a Sin(X) and Cos(X) pair, FSINCOS, inlining
@ 2003-07-09 20:30 Gautier Write-only
  2003-07-09 20:40 ` Florian Weimer
                   ` (2 more replies)
  0 siblings, 3 replies; 5+ messages in thread
From: Gautier Write-only @ 2003-07-09 20:30 UTC (permalink / raw)


Hello!

In some FPUs (like the Intel x387), Sin and Cos are computed simultaneously.
There is an instruction (Intel x387: FSINCOS) to get both together for +/- the
time cost of one of each.

Is there a way to make a compiler inline sufficienly the Run-Time library
and detect cases where Sin(X) and Cos(X) are in one area and X is the
same expression, in order to produce a FSINCOS instruction ?

(Example: in GNAT's Ada.Numerics.Generic_Complex_Elementary_Functions :
   function Exp (X : Imaginary) return Complex is
      ImX : Real'Base := Im (X);
   begin
      return Compose_From_Cartesian (Cos (ImX), Sin (ImX));
   end Exp;
)

I have tried with GNAT 3.15p for Win32 and the options "-gnatpN -O3", but
in vain. At best I obtain inlined FCOS and FSIN instructions, separately.
ObjectAda SE 7.2.2 (Win32, release mode) also computes Sin and Cos separately.
Of course there are also "safety belts" around both FPU calls that bring
more distance between them in the assembler code, making this optimization
perhaps less likely to happen.

A solution would be to add a Sin_Cos procedure to the Ada 0Y standard.

TIA for any hint or debate.
________________________________________________________
Gautier  --  http://www.mysunrise.ch/users/gdm/gsoft.htm

NB: For a direct answer, e-mail address on the Web site!



^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: Compute a Sin(X) and Cos(X) pair, FSINCOS, inlining
  2003-07-09 20:30 Compute a Sin(X) and Cos(X) pair, FSINCOS, inlining Gautier Write-only
@ 2003-07-09 20:40 ` Florian Weimer
  2003-07-10  1:51 ` Jeffrey Carter
  2003-07-12  6:26 ` Gautier Write-only
  2 siblings, 0 replies; 5+ messages in thread
From: Florian Weimer @ 2003-07-09 20:40 UTC (permalink / raw)


Gautier Write-only <gautier@somewhere.nil> writes:

> Is there a way to make a compiler inline sufficienly the Run-Time library
> and detect cases where Sin(X) and Cos(X) are in one area and X is the
> same expression, in order to produce a FSINCOS instruction ?

AFAIK, the x86 FSINCOS operation hasn't quote the semantics required
by the ARM.  But if GNAT already uses FSIN and FCOS directly, this
shouldn't be a real problem.

> A solution would be to add a Sin_Cos procedure to the Ada 0Y standard.

It's probably easier to add a new pipehole optimization to GCC. 8-)



^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: Compute a Sin(X) and Cos(X) pair, FSINCOS, inlining
  2003-07-09 20:30 Compute a Sin(X) and Cos(X) pair, FSINCOS, inlining Gautier Write-only
  2003-07-09 20:40 ` Florian Weimer
@ 2003-07-10  1:51 ` Jeffrey Carter
  2003-07-12  6:26 ` Gautier Write-only
  2 siblings, 0 replies; 5+ messages in thread
From: Jeffrey Carter @ 2003-07-10  1:51 UTC (permalink / raw)


Gautier Write-only wrote:
 >
 > In some FPUs (like the Intel x387), Sin and Cos are computed
 > simultaneously. There is an instruction (Intel x387: FSINCOS) to get
 > both together for +/- the time cost of one of each.

And in some FPUs they're not. So you're not going to get language 
support for such a platform-dependent thing. Probably the best thing you 
can hope for is a compiler- and platform-dependent package with such a 
function.

Most likely, you'll have to write your own using a machine-code insertion.

-- 
Jeff Carter
"If you think you got a nasty taunting this time,
you ain't heard nothing yet!"
Monty Python and the Holy Grail




^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: Compute a Sin(X) and Cos(X) pair, FSINCOS, inlining
  2003-07-09 20:30 Compute a Sin(X) and Cos(X) pair, FSINCOS, inlining Gautier Write-only
  2003-07-09 20:40 ` Florian Weimer
  2003-07-10  1:51 ` Jeffrey Carter
@ 2003-07-12  6:26 ` Gautier Write-only
  2003-07-13 23:32   ` Jerry van Dijk
  2 siblings, 1 reply; 5+ messages in thread
From: Gautier Write-only @ 2003-07-12  6:26 UTC (permalink / raw)


Jerry van Dijk:

# Sorry, the original article already scrolled off my system.

Nice... (what system! even with on a VT220 I could scroll up news ;-)

# Although there are very good reasons not to, if you are really need it,
# why not define your own, something like (could probably be improved, it's 
# been a while...):

[the correct one:]

   procedure Sin_Cos (Angle : Float; Sin : out Float; Cos : out Float);
   pragma Inline (Sin_Cos);

   procedure Sin_Cos (Angle : Float; Sin : out Float; Cos : out Float) is
      use ASCII;
   begin
      Asm (("fsincos"  & LF & HT &
            "fstp  %0" & LF & HT &
            "fst   %1"),
           Outputs => (Float'Asm_Output ("=m", Cos),
                      (Float'Asm_Output ("=m", Sin))),
           Inputs  => (Float'Asm_Input ("t", Angle)));
   end Sin_Cos;

Thanks! I don't have an urgent need but one never knows...
BTW, what is the variant for Long_Float ?
In any case, it would be nice to have a compiler producing FSINCOS - e.g.
for those users not familiar with machine code.
________________________________________________________
Gautier  --  http://www.mysunrise.ch/users/gdm/gsoft.htm

NB: For a direct answer, e-mail address on the Web site!



^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: Compute a Sin(X) and Cos(X) pair, FSINCOS, inlining
  2003-07-12  6:26 ` Gautier Write-only
@ 2003-07-13 23:32   ` Jerry van Dijk
  0 siblings, 0 replies; 5+ messages in thread
From: Jerry van Dijk @ 2003-07-13 23:32 UTC (permalink / raw)



Gautier Write-only <gautier@somewhere.nil> writes:

> # Sorry, the original article already scrolled off my system.
> 
> Nice... (what system! even with on a VT220 I could scroll up news ;-)

Nah. I just hooked my VT220 clone to the serial port of my laptop, but
it didn't help... :-)

BTW, I always preferred the TeleVideo 970.

> BTW, what is the variant for Long_Float ?

Here is a full example of both:

------------------------------------------------------------------------------
with Ada.Text_IO;                       use Ada.Text_IO;
with Ada.Numerics;                      use Ada.Numerics;
with System.Machine_Code;               use System.Machine_Code;

with Ada.Numerics.Generic_Elementary_Functions;

procedure Check is

   package Float_Funcs is new
     Ada.Numerics.Generic_Elementary_Functions (Float);
   use Float_Funcs;

   package Long_Float_Funcs is new
     Ada.Numerics.Generic_Elementary_Functions (Long_Float);
   use Long_Float_Funcs;

   procedure Sin_Cos (Angle : Float; Sin : out Float; Cos : out Float);
   procedure Sin_Cos
     (Angle : Long_Float; Sin : out Long_Float; Cos : out Long_Float);
   pragma Inline (Sin_Cos);

   procedure Sin_Cos (Angle : Float; Sin : out Float; Cos : out Float) is
      use ASCII;
   begin
      Asm (("fsincos"  & LF & HT &
            "fstp  %0" & LF & HT &
            "fst   %1"),
           Outputs => (Float'Asm_Output ("=m", Cos),
                      (Float'Asm_Output ("=m", Sin))),
           Inputs  => (Float'Asm_Input ("t", Angle)));
   end Sin_Cos;

   procedure Sin_Cos
     (Angle : Long_Float; Sin : out Long_Float; Cos : out Long_Float) is
      use ASCII;
   begin
      Asm (("fsincos"  & LF & HT &
            "fstpl  %0" & LF & HT &
            "fstl   %1"),
           Outputs => (Long_Float'Asm_Output ("=m", Cos),
                      (Long_Float'Asm_Output ("=m", Sin))),
           Inputs  => (Long_Float'Asm_Input ("t", Angle)));
   end Sin_Cos;

   package IO_Concats is
      function "&" (S : String; F : Float) return String;
      function "&" (S : String; F : Long_Float) return String;
   end IO_Concats;

   package body IO_Concats is

      function "&" (S : String; F : Float) return String is
      begin
         return S & Float'Image (F);
      end "&";

      function "&" (S : String; F : Long_Float) return String is
      begin
         return S & Long_Float'Image (F);
      end "&";

   end IO_Concats;

   use IO_Concats;

   Sin_Float, Cos_Float : Float;
   Float_Value : constant Float := 0.25 * Pi;

   Sin_Long_Float, Cos_Long_Float : Long_Float;
   Long_Float_Value : constant Long_Float := 0.25 * Pi;

begin

   Sin_Float := Sin (Float_Value);
   Cos_Float := Cos (Float_Value);
   Put_Line ("Sin_Float:" & Sin_Float & ", Cos_Float:" & Cos_Float);

   Sin_Cos (Float_Value, Sin_Float, Cos_Float);
   Put_Line ("Sin_Float:" & Sin_Float & ", Cos_Float:" & Cos_Float);

   Sin_Long_Float := Sin (Long_Float_Value);
   Cos_Long_Float := Cos (Long_Float_Value);
   Put_Line
     ("Sin_LFloat:" & Sin_Long_Float & ", Cos_LFloat:" & Cos_Long_Float);

   Sin_Cos (Long_Float_Value, Sin_Long_Float, Cos_Long_Float);
   Put_Line
     ("Sin_LFloat:" & Sin_Long_Float & ", Cos_LFloat:" & Cos_Long_Float);

end Check;
-------------------------------------------------------------------------------

> In any case, it would be nice to have a compiler producing FSINCOS - e.g.
> for those users not familiar with machine code.

Yes. Have you checked gcc 3.3 ? Probably the Fortran folks would like this
too.

-- 
--  Jerry van Dijk   | email: jvandyk@attglobal.net
--  Leiden, Holland  | web:   users.ncrvnet.nl/gmvdijk



^ permalink raw reply	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2003-07-13 23:32 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2003-07-09 20:30 Compute a Sin(X) and Cos(X) pair, FSINCOS, inlining Gautier Write-only
2003-07-09 20:40 ` Florian Weimer
2003-07-10  1:51 ` Jeffrey Carter
2003-07-12  6:26 ` Gautier Write-only
2003-07-13 23:32   ` Jerry van Dijk

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox