comp.lang.ada
 help / color / mirror / Atom feed
From: Anh Vo <anhvofrcaus@gmail.com>
Subject: Re: GNAT's Protected Objects
Date: Mon, 8 Nov 2010 17:50:24 -0800 (PST)
Date: 2010-11-08T17:50:24-08:00	[thread overview]
Message-ID: <6ede403f-7c92-4edc-82c3-1bc85cbc9cb7@b19g2000prj.googlegroups.com> (raw)
In-Reply-To: ib9ts1$91l$1@tornado.tornevall.net

On Nov 8, 2:32 pm, Jeffrey Carter <spam.jrcarter....@spam.not.acm.org>
wrote:
> On 11/08/2010 02:38 PM, Anh Vo wrote:
>
>
>
> > How may tasks used, two or four, when slowness was observed when
> > compared to simple task? I will be supprised if the answer is two. It
> > is logically expected that two tasks should perform better than single
> > task. However, when it comes to four or greater task, the result may
> > not be true due to task switching cost.
>
> That's what I expected. However, any number of tasks > 1 took longer than a
> single task.
>
> > I would be glad to test it on my two core CPU mahine if the your
> > little program is posted.
>
> I have appended the code to this message. Watch for line wrapping.
>
> --
> Jeff Carter
> "Sir Robin the not-quite-so-brave-as-Sir-Lancelot,
> who had nearly fought the Dragon of Angnor,
> who nearly stood up to the vicious Chicken of Bristol,
> and who had personally wet himself at the
> Battle of Badon Hill."
> Monty Python & the Holy Grail
> 68
>
> with Ada.Exceptions;
> with Ada.Numerics.Float_Random;
> with Ada.Real_Time;
> with Ada.Text_IO;
>
> with System.Task_Info;
>
> procedure MP_Mult_PO is
>     Num_Processors : constant Positive := System.Task_Info.Number_Of_Processors;
>
>     subtype Index_Value is Integer range 1 .. 500;
>
>     type Matrix is array (Index_Value, Index_Value) of Float;
>
>     function Mult (Left : in Matrix; Right : in Matrix; Num_Tasks : in Positive)
> return Matrix;
>     -- Perform a concurrent multiplication of Left * Right using Num_Tasks tasks
>
>     function Mult (Left : in Matrix; Right : in Matrix; Num_Tasks : in Positive)
> return Matrix is
>        task type Calc_One;
>
>        protected Control is
>           procedure Get (Row : out Natural; Col : out Natural);
>           -- Returns the row and column of a result to calculate.
>           -- Returns zero for both when there are no more results to calculate.
>        private -- Control
>           Next_Row : Positive := 1;
>           Next_Col : Positive := 1;
>           Done     : Boolean  := False;
>        end Control;
>
>        Result : Matrix;
>
>        task body Calc_One is
>           Row : Natural;
>           Col : Natural;
>        begin -- Calc_One
>           All_Results : loop
>              Control.Get (Row => Row, Col => Col);
>
>              exit All_Results when Row = 0;
>
>              Result (Row, Col) := 0.0;
>
>              Sum : for K in Index_Value loop
>                 Result (Row, Col) := Result (Row, Col) + Left (Row, K) * Right
> (K, Col);
>              end loop Sum;
>           end loop All_Results;
>        exception -- Calc_One
>        when E : others =>
>           Ada.Text_IO.Put_Line (Item => "Calc_One " &
> Ada.Exceptions.Exception_Information (E) );
>        end Calc_One;
>
>        protected body Control is
>           procedure Get (Row : out Natural; Col : out Natural) is
>           begin -- Get
>              if Done then
>                 Row := 0;
>                 Col := 0;
>
>                 return;
>              end if;
>
>              Row := Next_Row;
>              Col := Next_Col;
>
>              if Next_Col < Index_Value'Last then
>                 Next_Col := Next_Col + 1;
>
>                 return;
>              end if;
>
>              Next_Col := 1;
>              Next_Row := Next_Row + 1;
>
>              Done := Next_Row > Index_Value'Last;
>           end Get;
>        end Control;
>     begin -- Mult
>        Create_Tasks : declare
>           type Task_List is array (1 .. Num_Tasks) of Calc_One;
>
>           Tasks : Task_List;
>        begin -- Create_Tasks
>           null; -- Wait for all tasks to complete
>        end Create_Tasks;
>
>        return Result;
>     exception -- Mult
>     when E : others =>
>        Ada.Text_IO.Put_Line (Item => "Mult " &
> Ada.Exceptions.Exception_Information (E) );
>
>        raise;
>     end Mult;
>
>     function Random return Float;
>
>     Gen : Ada.Numerics.Float_Random.Generator;
>
>     function Random return Float is
>     begin -- Random
>        return 200.0 * Ada.Numerics.Float_Random.Random (Gen) - 100.0; -- -100 ..
> 100.
>     end Random;
>
>     A : constant Matrix := Matrix'(others => (others => Random) );
>     B : constant Matrix := Matrix'(others => (others => Random) );
>
>     C : Matrix;
>
>     Elapsed   : Duration;
>     Prev      : Duration := Duration'Last;
>     Start     : Ada.Real_Time.Time;
>     Num_Tasks : Positive := 1;
>
>     use type Ada.Real_Time.Time;
> begin -- MP_Mult_PO
>     Ada.Text_IO.Put_Line (Item => "Num processors" & Integer'Image
> (Num_Processors) );
>
>     All_Calls : loop
>        Start := Ada.Real_Time.Clock;
>        C := Mult (A, B, Num_Tasks);
>        Elapsed := Ada.Real_Time.To_Duration (Ada.Real_Time.Clock - Start);
>        Ada.Text_IO.Put_Line (Item => Integer'Image (Num_Tasks) & ' ' &
> Duration'Image (Elapsed) );
>
>        exit All_Calls when Num_Tasks > 2 * Num_Processors and Elapsed > Prev;
>
>        Prev := Elapsed;
>        Num_Tasks := Num_Tasks + 1;
>     end loop All_Calls;
> exception -- MP_Mult_PO
> when E : others =>
>     Ada.Text_IO.Put_Line (Item => "MP_Mult_PO " &
> Ada.Exceptions.Exception_Information (E) );
> end MP_Mult_PO;

Below are the test results conducted on GNAT 2010 running on Windows
XP.

Num processors 2
 1  0.077000009
 2  0.055627741
 3  0.023719495
 4  0.018366580
 5  0.018512129

The output looks reasonable. The speed is improved up to 4 tasks. It
slows down with 5 tasks due to tasking switch. However, it is still
better than single task.

As Robert suggested, I would divide work among tasks by passing
paramter into each task. For example, in case of two tasks, one task
handles from rows 1 .. 250 while the other task handle from rows
251 .. 500. By the way, the protected singleton type Control is no
longer needed.

Anh Vo



  parent reply	other threads:[~2010-11-09  1:50 UTC|newest]

Thread overview: 17+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2010-11-08 20:34 GNAT's Protected Objects Jeffrey Carter
2010-11-08 21:38 ` Anh Vo
2010-11-08 22:32   ` Jeffrey Carter
2010-11-08 22:43     ` Robert A Duff
2010-11-09  0:27       ` Jeffrey Carter
2010-11-09 14:21         ` Robert A Duff
2010-11-09 18:23           ` Jeffrey Carter
2010-11-09 10:05       ` Egil Høvik
2010-11-09  1:50     ` Anh Vo [this message]
2010-11-09  3:14       ` Jeffrey Carter
2010-11-09  2:03     ` Peter C. Chapin
2010-11-09 10:18     ` Egil Høvik
2010-11-09 11:17       ` Julian Leyh
2010-11-09 18:22       ` Jeffrey Carter
     [not found] ` <s5GdnRvDRfR6-0XRnZ2dnUVZ_hOdnZ2d@earthlink.com>
2010-11-08 22:41   ` Jeffrey Carter
2010-11-09 10:36 ` Maciej Sobczak
2010-11-24  7:08 ` Brad Moore
replies disabled

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