Re: Lahman, how ya doing?
- From: glhansen@xxxxxxxxxxxxxxxxxxxxx (Gregory L. Hansen)
- Date: Wed, 27 Apr 2005 20:50:43 +0000 (UTC)
In article <%MRbe.7644$WX.5286@trndny01>,
H. S. Lahman <hsl@xxxxxxxxxxxxxxxxx> wrote:
>Responding to Hansen...
>
>> I also need jobs that do task 1 at time interval 1, and task 2 at time
>> interval 2. But it won't be hard to add a
>>
>> time.add_task(&c3, 5, 20);
>
>At the risk of being picky, doesn't this do the /same/ task twice?
No. In the system I want to simulate, there's a sampling time of, say,
one second, and an averaging time of, say, 60 seconds. Once per second it
takes a data point and calculates a running total and total^2, and once
per 60 seconds it calculates and reports an average and standard
deviation, and zeroes the totals.
The code wouldn't work with just any old object you throw into it. But
I'm trying to build a Swiss Army knife. It's also probably not actually
necessary for a simulation, but I had an evolution of the original
implementation in mind. I should consider changing that.
>
>I am a little nervous about the notion of 'interval'. That sounds like
>a hard real-time constraint. I assume this is a delay for settling
>times or something. But first let me digress to look at the vanilla
>precedence view where all one needs to do is ensure some task completes
>before another starts.
Data samples are taken every second and averaged every 60, the control
system samples and adjusts every 7/60 second (incommensurate with 60 Hz
line noise), the state of the beam changes every half hour, and the
analog peices are analog and don't really have an iteration time but
should at least be faster than the control system. Those are the
intervals.
It's a simulation, so simulated time will be frozen until all tasks
complete, in the sense of e.g. getting an input voltage and calculating
the output of a simulated gain and filter.
Which brings up another member function I've added, timer.update_tasks().
I don't want, say, a thermal block at t=10s to be getting a heat input
from another block at t=10.1s. So the new state in each block will be
saved until they've all been processed, and then transferred to the
current state.
>
>You kind of get that for free if you use a single event queue and
>popping an event doesn't return in the event queue manager until the
>task is completed. If, though, the timer event is only one of several
>events that may be issued to complete tasks, one needs a different
>mechanism.
What I've done so far, I don't think you could really call an event queue.
Each task keeps a wait_time and a next_event, and executes and updates
when polled with a time >= next_event. Since it's a simulation, I don't
think it's really sensible to have an event queue. It's not going to be
waiting for a user to decide to click the mouse or anything, except
externally to the simulation.
>
>The approach you suggest here assumes you know <fairly> exactly how long
>the preceding task will take to execute. That delay then gets
>parameterized into the Timer. IOW, task0 goes at t0, task1 goes at t0 +
>interval1, and task2 goes at t0 + interval2. That may work fine if the
>intervals have a lot of safety in them, but there are some potential
>pitfalls.
Well, since it's a simulation, it has basically infinite time.
>
>Mainly you at the mercy of the accuracy of intervalN, which is
>cumulative with the N-1 previous tasks. If the processing times or the
>order or processing change it may not be obvious that the Timer
>parameters need to change. Another possible problem is a race condition
>if there is another set of dependent tasks that are triggered from a
>different t0 in the timer. Yet another problem is that if the
>intervalNs have lots of builtin safety, the application may be sitting
>on its thumbs a lot of the time and that might reduce your accuracy
>because you are effectively reducing the sample size. (Obviously less
>of a problem if you /need/ a delay for settling or whatever.)
I actually need to calculate the settling explicitly since my little
project is not connected to any physical system. The settling is the main
point of interest.
>
>A more rigorous approach that gets around these problems is simple
>daisy-chaining of the tasks. When a prerequisite task finishes, it
>generates the trigger event for the next task rather than the timer.
>Now the Timer just needs to generate events for the initial task in each
>set of dependent tasks or an event for some overall periodicity.
I guess that's sort of what I'm doing. Except the tasks aren't
daisy-chained, the timer just triggers them one by one.
>
>Note that one can even change the role of the Timer from doling out
>events based on clock ticks to a arbitrator. Suppose you have an
>Activity Diagram with multiple dependencies among tasks like
>
>Task1 task2 task3
> | | |
> +----+ +----+ |
> | | |
> ===== |
> | |
> task4 |
> | |
> +-------+ +------+
> | |
> =====
> |
> task5
>
>Now the Timer can manage a suite of semaphores for the tasks. It starts
>off with one task, say task2 and sends it a trigger event. When task2
>completes, it sends back an I'm done event to Timer. Timer then sets
>the task2 semaphore and and checks its rules (each task has a bitmap of
>semaphores that must be set for it to execute). It selects some task
>whose prerequisites are done, say task3. And so on... When all the
>semaphores are set, Timer clears them and starts over.]
Not that I don't appreciate the insight; I'm reading it and thinking of
things to do with it. But I'm looking at a system more like
beam
|
heater --- thermal block 1 --- heat link --- thermal block 2 --- He bath
|
thermometer
There isn't a time sequence of events, every part of the system evolves
simultaneously. Heat goes from the heater to thermal block 1, heat goes
from thermal block 1 to the heat link and to block 2, the temperature and
resistance of the thermometer change as the heat load changes, all at the
same time. So at a given instant of simulation time I just freeze the
state and determine how much heat goes into and out of block 1, how much
heat goes into and out of block 2, how much does the temperature of the
thermometer change, etc.
There are some things (in the real system) like moving the shutter to turn
the beam on or off, but then block 1 just takes what it gets, it can't
wait for it.
What you've described seems more applicable to process control. Like open
valve A until so much water flows into a tank, open valve B until so much
syrup flows into it, operate the solids feeder until so many solids flow
in, blend until so many minutes after all materials have been added and
after the contents have reached a desired temperature, etc.
But all the directly controllable things that I'm doing, like changing the
beam or recording data, have fixed times, or else it's something like
analog heat flow that evolves continuously.
The only event that the real apparatus actually watches for is a mouse
click, to stop. Nothing else is event driven, it just goes through a
loop, checking TickCount() again and again to see if it's the scheduled
time to sample a voltage or move the shutter or something. You could
write out a schedule of events for every change of state of the system in
advance.
>
>So what about delays? I went through this because life is rarely
>simple. I see the inherent sequencing as a distinct problem from the
>delays. The delay is something one does /after/ deciding one could do
>something. So on general principle I am not comfortable with Timer
>addressing both issues. If one separates the delay concern, then it
>doesn't matter which approach above is used to determine when the delay
>should start counting.
>
>Let Timer send an event to a Delay instance for the relevant task once
>that tasks' prerequisites are in place. The Delay does it own tick
>counting for the interval and then issues the actual event that triggers
>the relevant task. IOW, I could see the state machine for Delay looking
>something like:
>
> E1:start
> [Reset] <------------------- [Idle]
> | |
> | E2:timer tick | E4:task completed
> | |
> V |
>+----- [Counting] ---------------> [Delay Completed]
>| ^ E3:trigger
>| |
>+-----------+
> E2:timer tick
>
>Timer sends the E1:start event when the task is eligible to execute. It
>also sends E2:timer tick events that are ignored unless the current
>state is [Reset] or [Counting]. The [Counting] state just counts the
>ticks until the predefined number for the delay, in which case it
>generates E3:trigger to itself. The [Delay Completed] state just
>generates the actual processing triggering event to the task object.
>When the task is completed it sends back the E4:task completed event.
>If Timer is being fancy with dependencies, then the [Idle] state sends
>an event to Timer to announce the task is done so it can set its
>semaphore or whatever.
>
>This might seem like overkill, especially when one realizes the only
>things these states do is send events and initialize, increment, and
>check a counter attribute. But the state machine is actually capturing
If I had to do something like one block waiting for another block to
finish something, with the logic I'm currently working with, I'd probably
just give the one block a flag, "completed" or "not completed", and the
other block would poll it every time it ticks, and do its own record
keeping concerning when it starts and stops and etc. (Keeping in mind I
don't have anything like contact switches to poll, although I could
simulate contact switches.)
>rules statically and one has completely isolated all the delay logic
>from both the Timer and the relevant Task. That is reflected in the
But maybe that's not the kind of delay you had in mind.
>fact that the Timer and Task know nothing about delays; the only "logic"
>they have is issuing the E1, E2, and E4 events. So one can insert or
>remove a delay by just changing where the events go. As a bonus, all
>delays have exactly the same processing (modified parametrically by
>providing a tick count to compare when the Delay object is
>instantiated). IOW, it is statically significantly more complicated but
>dynamically simpler and more robust.
>
>
>*************
>There is nothing wrong with me that could
>not be cured by a capful of Drano.
>
>H. S. Lahman
>hsl@xxxxxxxxxxxxxxxxx
>Pathfinder Solutions -- Put MDA to Work
>http://www.pathfindermda.com
>blog: http://pathfinderpeople.blogs.com/hslahman
>(888)OOA-PATH
>
>
>
--
Irony: "Small businesses want relief from the flood of spam clogging their
in-boxes, but they fear a proposed national 'Do Not Spam' registry will
make it impossible to use e-mail as a marketing tool."
http://www.bizjournals.com/houston/stories/2003/11/10/newscolumn6.html
.
- Follow-Ups:
- Re: Lahman, how ya doing?
- From: H. S. Lahman
- Re: Lahman, how ya doing?
- References:
- Lahman, how ya doing?
- From: Gregory L. Hansen
- Re: Lahman, how ya doing?
- From: H. S. Lahman
- Re: Lahman, how ya doing?
- From: Gregory L. Hansen
- Re: Lahman, how ya doing?
- From: H. S. Lahman
- Lahman, how ya doing?
- Prev by Date: Re: Lahman, how ya doing?
- Next by Date: complicated emulation problem
- Previous by thread: Re: Lahman, how ya doing?
- Next by thread: Re: Lahman, how ya doing?
- Index(es):
Relevant Pages
|
Loading