comp.lang.ada
 help / color / mirror / Atom feed
From: "Randy Brukardt" <randy@rrsoftware.com>
Subject: Re: Real tasking problems with Ada.
Date: Wed, 2 Aug 2017 23:16:38 -0500
Date: 2017-08-02T23:16:38-05:00	[thread overview]
Message-ID: <olu837$q2t$1@franka.jacob-sparre.dk> (raw)
In-Reply-To: f9e87130-3f08-43c4-8cc6-9e164a6da954@googlegroups.com

"Robert Eachus" <rieachus@comcast.net> wrote in message 
news:f9e87130-3f08-43c4-8cc6-9e164a6da954@googlegroups.com...
On Tuesday, August 1, 2017 at 12:42:01 AM UTC-4, Randy Brukardt wrote:

>> Use a discriminant of type CPU and (in Ada 2020) an
>> iterated_component_association. (This was suggested way back in Ada 9x, 
>> left
>> out in the infamous "scope reduction", and then forgotten about until 
>> 2013.
>> See AI12-0061-1 or the draft RM
>> http://www.ada-auth.org/standards/2xaarm/html/AA-4-3-3.html).
>
>It is nice that this is in there, just in-time to be outmoded.  See my 
>previous post,
>on most desktop and server processors assigning to alternate processor IDs 
>is
> necessary.

Why would that be "outmoded"? What's wrong with:
    (for I in 1..Number_of_CPUs/2 => new My_Task (The_CPU => I*2));
if you need alternate CPUs? Or, even better, a function call to map the 
linear array indexes to CPUs? This is all dynamic code, after all, write 
anything you need.

>> Why do you say this? Ada doesn't require the task that calls a protected
>> object to execute it (the execution can be handdled by the task that
>> services the barriers - I don't know if any implementation actually does
>> this, but the language rules are written to allow it).

>Um, I say it because any other result is useless?  The use case is for the
>called task or protected object to be able to get the CPU number and
>do something with it.

But that's a nonsense use-case. You're not allowed to ask the Current_Task 
in an entry body or interrupt handler (see C.7.1(17/3) -- the operation is 
allowed to raise Program_Error or return an implementation-defined Task_Id). 
So it's nonsense to ask what CPU you're running on when you're not even 
allowed to ask what task is running.

> The simple case right now would be a protected object whose only purpose
> is to make sure task assignments are compatible with the architecture.

But that's backwards; you use a function to make those assignments when the 
tasks are created. (Again, if you're in a Ravenscar environment, you can't 
do that, but the code has to be tied to a particular CPU layout when it 
compiled, so there's nothing to check.)

...
>> Say what? You're using Get_Id, so clearly you're using something there.
>> Get_Id (like the rest of dispatching domains is likely to be expensive, 
>> so
>> you don't want it dragged into all programs. (And CPU is effectively part 
>> of
>> all programs.)
>
>Sigh! Get_Id as defined is heavy only because of the default initial value:
>
>   function Get_CPU
>     (T   : Ada.Task_Identification.Task_Id :=
>                 Ada.Task_Identification.Current_Task)
>          return CPU_Range;
>
>but a parameterless Get_CPU could compile to a single load instruction.

No chance. You have to make a kernel call to get any thread information 
(like affinities), and that's likely to be more expensive than any task id 
stuff. That "single load instruction" is protected on every archtecture I've 
dealt with, and the kernels don't let programs mess with those instructions 
(and rightly so).

You seem to be thinking of bare machine implementations of Ada, but none of 
those that have existed in the last decade or more have any tasking support. 
Customers aren't interested in such things so far as I can tell. (And I 
agree this is a sad state of affairs, but complaining about it isn't going 
to change anything. I've been told in ARG meetings not to worry about bare 
machine implementations for this reason.)

In any case, you can avoid any heaviness from the default parameter by 
actually providing the task id you need to know about.

...
>> So the capability already exists, but you don't like having to with an 
>> extra
>> package to use it? Have you lost your freaking mind? You want us to add
>> operations that ALREADY EXIST to another package, with all of the
>> compatibility problems that doing so would cause (especially for people 
>> that
>> had withed and used Dispatching_Domains)? When there are lots of problems
>> that can't be solved portably at all?
>
>No, I don't want compilers putting in extra code when it is not necessary. 
>If a
> task has a (static) CPU assignment then again, Get_CPU is essentially 
> free.

No way; you have to get that information from the kernel. So long as Set_CPU 
exists you have to assume that it could have been used. It's only free if 
you've put it into a well-known place (say the discriminant of the task 
type) and read it from there, because you know you didn't use Set_CPU. (Also 
note, at least in the cases of the systems I've worked on, that we don't 
store anything that can be changed by kernel operations in the Ada runtime 
system, so that if someone uses kernel operations to change the values, we 
actually report the real answer and not the one that the compiler knows 
about.)

>Is it cheaper than fishing some index out of main memory because it got
>flushed there? Probably.  Yes, I can make a function My_CPU which
>does this.  I'm just making too many of those workarounds right now.

I don't think this is a workaround. It's WAY cheaper to get this information 
yourself than it is to get it from the kernel.

>> >A function Cache_Line_Size in System or System.Multiprocessors seems 
>> >right.
>>
>> No,  it doesn't. It assumes a particular memory organization, and one 
>> thing
>> that's pretty clear is that whatever memory organization is common now 
>> will
>> not be common in a bunch of years. Besides, so many systems have multiple
>> layers of caches, that a single result won't be enough. And there is no 
>> way
>> for a general implementation to find this out (neither CPUs nor kernels
>> describe such information).

>Um. No.  Systems may have multiple levels of caches of different sizes and
>different numbers of "ways" per cache.  But the actual cache line size is
>almost locked in, and is the same for all caches in a system.  Most systems
>with DDR3 and DDR4 use 64 byte cache lines because it matches the
>memory burst length.  But other values are possible.  Right now HBM2
>is pushing GPUs (not CPUs) to 256 byte cache lines.  Will we eventually
>have Ada compilers generating code for heterogeneous systems?  Possible.
>What I am working on is building the blocks that can be used with
>DirectCompute, OpenCL 2.0, and perhaps other GPU software interfaces.

But you didn't answer the actual question. How in the world would an Ada 
compiler figure out the cache line size? I have no clue as to what it is on 
the computer that I'm writing them on, and it's not something that is 
provided by Windows or Linux. So how could an Ada runtime figure out it out 
and report it?? Janus/Ada programs run on any Win32 system from Windows 95 
on, it's wildly impractical to have some sort of hardware table.

As far as hetrogeneous systems go, you have to assume that (especially in a 
case like this). It would be awful to prevent that just for a little-used 
function. So there can't be an unconditional "cache-line" setting, it has to 
be based on a particular piece of memory. (It's similar in that way to file 
systems; you can have both case-sensitive and case-preserving file systems 
on the same computer and even in the same program.) That's one complication 
of several with discussing "cache-lines", not to mention that the entire 
concept will most likely be gone in a decade.

                            Randy.



  parent reply	other threads:[~2017-08-03  4:16 UTC|newest]

Thread overview: 23+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2017-07-25 23:19 Real tasking problems with Ada Robert Eachus
2017-07-26 19:42 ` sbelmont700
2017-07-27  2:00   ` Robert Eachus
2017-08-01  4:45     ` Randy Brukardt
2017-08-02  2:23       ` Robert Eachus
2017-08-03  3:43         ` Randy Brukardt
2017-08-03 20:03           ` Robert Eachus
2017-08-03 23:10             ` Luke A. Guest
2017-08-04 23:22             ` Randy Brukardt
2017-08-22  5:10               ` Robert Eachus
2017-08-01  4:41 ` Randy Brukardt
2017-08-02  3:44   ` Robert Eachus
2017-08-02 14:39     ` Lucretia
2017-08-03  0:57       ` Robert Eachus
2017-08-03  5:43         ` Randy Brukardt
2017-08-03  1:33       ` Wesley Pan
2017-08-03  4:30       ` Randy Brukardt
2017-08-03  4:16     ` Randy Brukardt [this message]
2017-08-03  5:05       ` Niklas Holsti
2017-08-04 23:11         ` Randy Brukardt
2017-08-05  7:01           ` Niklas Holsti
2017-08-03  8:03     ` Simon Wright
2017-08-04 23:16       ` Randy Brukardt
replies disabled

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