From mboxrd@z Thu Jan 1 00:00:00 1970 X-Spam-Checker-Version: SpamAssassin 3.4.4 (2020-01-24) on polar.synack.me X-Spam-Level: X-Spam-Status: No, score=-1.9 required=5.0 tests=BAYES_00,FREEMAIL_FROM autolearn=ham autolearn_force=no version=3.4.4 X-Google-Language: ENGLISH,ASCII-7-bit X-Google-Thread: 103376,1769ac558c6fa259,start X-Google-Attributes: gid103376,public X-Google-ArrivalTime: 2002-02-21 04:37:58 PST Path: archiver1.google.com!postnews1.google.com!not-for-mail From: karlran1234@yahoo.com (Karl Ran) Newsgroups: comp.lang.ada Subject: How to speed up stream & record handling? Date: 21 Feb 2002 04:37:57 -0800 Organization: http://groups.google.com/ Message-ID: NNTP-Posting-Host: 217.227.64.162 Content-Type: text/plain; charset=ISO-8859-1 Content-Transfer-Encoding: 8bit X-Trace: posting.google.com 1014295078 20180 127.0.0.1 (21 Feb 2002 12:37:58 GMT) X-Complaints-To: groups-abuse@google.com NNTP-Posting-Date: 21 Feb 2002 12:37:58 GMT Xref: archiver1.google.com comp.lang.ada:20206 Date: 2002-02-21T12:37:58+00:00 List-Id: 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;