comp.lang.ada
 help / color / mirror / Atom feed
From: karlran1234@yahoo.com (Karl Ran)
Subject: How to speed up stream & record handling?
Date: 21 Feb 2002 04:37:57 -0800
Date: 2002-02-21T12:37:58+00:00	[thread overview]
Message-ID: <e7ebd224.0202210437.1c7d0fbf@posting.google.com> (raw)

Hello,
I've a problem getting a reasonable IO preformance from an Ada
program (source is attached)

The environment looks like this:
OS: linux-2.4.16
CPU: Intel P3/700 MHz / BX chipset
compiler: gnat-3.14p

The program reads a packet of data (200 bytes) and converts the
header(2 bytes) to match the architecture.  It will do it 100000 times.

>time ./slow_ada
real    0m8.545s
user    0m8.350s <- looks like it spend all the time in the ada-code!
sys     0m0.070s

Thats 20 MByte / 8.5 seconds = 2.4 MByte/sec

It's too slow for the target application.

Has anyone an idea on how to speed up this progam, other than
throwing more CPU-power at the problem?

OK,
I know the the PC achitecture is known for their bad IO performance,
but this 2.4 MBytes/s seems not be related to the PC-IO-bottleneck...  

Thanks,
Karl   

with Ada.Text_IO;
with Ada.Streams.Stream_IO;
with System;

procedure Slow_Ada is

   type Unsigned_4 is mod 2 **4;
   for Unsigned_4'Size use 4;

   type Unsigned_8 is mod 2 ** 8;
   for Unsigned_8'Size use 8;

   type Unsigned_12 is mod 2 ** 12;
   for Unsigned_12'Size use 12;

   type Data_array is array( 1 .. 198 ) of Unsigned_8;

   -- Because a single byte is occupied by Both part of B and all of C,
   -- We combine them into a record so we can define stream-oriented
   -- attributes such that they can be read and written from/to a stream
   -- properly, regardless of machine endianness.

   type B_And_C is
      record
        B : Unsigned_12;
        C : Unsigned_4;
      end record;

   -- Use this representation clause on a little-endian machine.
   for B_And_C use
     record at mod 1;
        B at 0 range 4 .. 15;
        C at 0 range 0 .. 3;
     end record;

   -- Use this representation clause on a big-endian machine.
--    for B_and_C use
--      record at mod 1;
--         B at 0 range 0 .. 11;
--         C at 0 range 12 .. 15;
--      end record;

   for B_And_C'Size use 16;

   -- We now procedd to declare the stream-orientd attributes
   procedure B_And_C_Read
     (Stream : access Ada.Streams.Root_Stream_Type'Class;
      Item   : out     B_And_C);

   procedure B_And_C_Write
     (Stream : access Ada.Streams.Root_Stream_Type'Class;
      Item   : in     B_And_C);

   for B_And_C'Read use B_And_C_Read;

   for B_And_C'Write use B_And_C_Write;

   type My_Record is
     record
        A  : Data_array; -- 200 bytes
        BC : B_And_C;    --   2 bytes
     end record;

   type Byte_Array is array (Positive range <>) of Unsigned_8;

   -- This procedure reverses the oder of the bytes in its argument.
   procedure Swap (The_Bytes : in out Byte_Array) is
      Temp : Unsigned_8;
   begin
      for B in 1 .. The_Bytes'Last / 2 loop
         Temp := The_Bytes (B);
         The_Bytes (B) := The_Bytes (The_Bytes'Last - B + 1);
         The_Bytes (The_Bytes'Last - B + 1) := Temp;
      end loop;
   end Swap;


   -- These porocedures implement the stream-oriented attributes.
   procedure B_And_C_Read
     (Stream : access Ada.Streams.Root_Stream_Type'Class;
      Item   : out     B_And_C) is
      The_Bytes : Byte_Array (1 .. Item'Size / Unsigned_8'Size);
      for The_Bytes'Address use Item'Address;
      use type System.Bit_Order;
   begin
      Byte_Array'Read (Stream, The_Bytes);
      if System.Default_Bit_Order = System.Low_Order_First then
        Swap (The_Bytes);
      end if;
   end B_And_C_Read;

   procedure B_And_C_Write
     (Stream : access Ada.Streams.Root_Stream_Type'Class;
      Item   : in     B_And_C) is
      The_Bytes : Byte_Array (1 .. Item'Size / Unsigned_8'Size);
      for The_Bytes'Address use Item'Address;
      use type System.Bit_Order;
   begin
      if System.Default_Bit_Order = System.Low_Order_First then
        Swap (The_Bytes);
      end if;
      Byte_Array'Write (Stream, The_Bytes);
   end B_And_C_Write;

   Item : My_Record;

   File : Ada.Streams.Stream_IO.File_Type;

   Stream : Ada.Streams.Stream_IO.Stream_Access;
begin
   Ada.Streams.Stream_IO.Open
     (Name => "/dev/zero", --use any big file you like (20 MByte)
      File => File,
      Mode => Ada.Streams.Stream_IO.In_File);

   Stream := Ada.Streams.Stream_IO.Stream (File);

   for I in 1 .. 100000 loop

      My_Record'Read (Stream, Item);

   end loop;

   Ada.Streams.Stream_IO.Close (File);

end Slow_Ada;



             reply	other threads:[~2002-02-21 12:37 UTC|newest]

Thread overview: 8+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2002-02-21 12:37 Karl Ran [this message]
2002-02-21 14:17 ` How to speed up stream & record handling? Martin Dowie
2002-02-21 17:34 ` Jeffrey Carter
2002-02-21 20:25 ` Florian Weimer
2002-02-21 23:59   ` tmoran
2002-02-22 13:31     ` Karl Ran
2002-02-22 20:25       ` tmoran
2002-02-24  3:23 ` Nick Roberts
replies disabled

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