Co_Routines Support for Oberon

http://www.zinnamturm.eu/downloadsAC.htm#Co_ http://sourceforge.net/projects/ta1/files/co2.0
Dmitry Dagaev
Posts: 68
Joined: Wed Mar 29, 2017 3:58 pm

Re: Co_Routines Support for Oberon

Post by Dmitry Dagaev »

More precise measurements with background tasks.

I've compared calculation time for ObxCoroutines.RunPrimes and Co_ObxActions.StartPrimes.
Initial conditions:
1. modified Co_ObxActions to set Co.Yield in the same place, as in ObxCoroutines.
2. excluded time consuming primes logging calls.
3. set 100% CPU usage threshold for Co_ scheduler

Code: Select all

		s := Ct.scheduler;
		p.interval := 50;  (* 50 ms *)
		p.load_pct := 100;  (* 100% cpu *)
		s.SetParams(s, p);
Called parameters:
limit = 10000000

The results are (with 10% inaccuracy):
  • 37.80 sec - ObxCoroutines
  • 5.61 sec - Co_ObxActions
  • 18.1 sec - Co_ObxActions with default parameters (usage for bg tasks is 40% limited)
  • 5.41 sec - Co_ObxActions as foreground task (Co.Yield excluded)
User avatar
Robert
Posts: 177
Joined: Sat Sep 28, 2013 11:04 am
Location: Edinburgh, Scotland

Re: Co_Routines Support for Oberon

Post by Robert »

I have not had the time (and there are probably other reasons) to follow this discussion carefully, so I apologise if my remarks seem rather trivial.
Some time ago I had an algorithmic problem (a bit similar to the same frimge question) and found, on the internet, a solution described in terms of Python Iterators with Yields (if I remember correctly). I thought: "That's neat, but I can't see how to do that in Component Pascal". But it was apparent that a prettly simple understanding of a couple of language (Python) keywords gave access to a significant capability; the whole thing was not too scary.

This discussion is really quite scary for a potential very infrequent user of coroutines - I've only actively wanted them once in a lifetime! The Co package is 2 MByte (compressed); that alone makes one feel that it is aimed at the expert user who can cope with (and needs) very many specialised options.

Are we going in the direction of having two (or three if we think of Ivan's suggestions as an alternative) overlapping packages in both CPC & the Center distribution? That, I think, would make the subject even more inacessible for the new or casual user.

Is there a balance to be struck between the needs of the expert and the wishes of the beginner? Are we heading towards it? Or is such a compromise the worst of all worlds, and we should choose a target audience (experts, I guess) and pitch the development to their needs?

And what about the overlap between the 2014 Co_ subsystem and the 2017 Center proposals? Is it large overlap? Is it a good thing? Is it a bad thing?

And finally, why is the StdCoded version of Co_ 20 times bigger than the PacCoded version - normally the ratio is 2 or 3 to 1?
Dmitry Dagaev
Posts: 68
Joined: Wed Mar 29, 2017 3:58 pm

Re: Co_Routines Support for Oberon

Post by Dmitry Dagaev »

Robert wrote:The Co package is 2 MByte (compressed)
The extra size of Co_ and difference between StdCoded and PacCoded versions has the simple explanation. The Co_/Docu/Tasks.odc contains ONE image in bitmap format (task, coroutine, engine, process & thread connections from C.Szyperski "Insight-EthOS"). Just compare file sizes. The PacCoded algorithm compressed images more effectively.
Robert wrote:And what about the overlap between the 2014 Co_ subsystem and the 2017 Center proposals?
New Center version has pointers & traps Kernel support. Co_ system will be upgraded with new Kernel release.
Nevertheless, you can use Co_ in BB1.6 WHITHOUT calling NEW() inside a coroutine.
Robert wrote:quite scary for a potential very infrequent user of coroutines
We all must understand, that coroutines programming is a side step from well-proven Oberon way of writing software. In any implementation Transfer() calls move us back to 60-s when GOTO reigned the programming world. Moreover, there is not compiler support for special types of coroutines (unlike Python generators). Special patterns must be used in the application programs.

Event between authors there no shared vision: I had a lot of critics towards Josef's implementation, he claimed, that my implementation was too overfeatured to a novice. I answered, that basic functionality resides in (and so on):
Co_Tasks - Task for Cooperative Multitasking and base module for Co_Routines
Co_Routines - Implementation itself

From my side, maybe I'll reimplement next Co_ version in BlackBox style instead of Oberon-0 style.
Dmitry Dagaev
Posts: 68
Joined: Wed Mar 29, 2017 3:58 pm

Re: Co_Routines Support for Oberon

Post by Dmitry Dagaev »

Robert wrote:(and needs) very many specialised options
Co_ has also cooperative multitasking functionality and semaphores support.
The Co_Obx multitasking examples cannot be implemented in new Coroutines package:
  • Co_ObxPhilosophers - Dining Philosophers
  • Co_ObxProducerConsumer - Producer Consumer probler
  • Co_ObxReaderWriter - Reader Writer problem
Zinn
Posts: 123
Joined: Mon Nov 24, 2014 10:47 am
Location: Frankfurt am Main
Contact:

Re: Co_Routines Support for Oberon

Post by Zinn »

I’m confused. What is the different between Oberon-0 style and BlackBox style inside subsystem Co_? I see no competition between Dmitry and Josef. There was no BlackBox support for co-routines and the Co_ package has a problem with the garbage collection. I thought that Josef solved the garbage collection problem and provided the missing integration into BlackBox. Only Dmitry’s module Co_Routines need to be changed to use the new support. See viewtopic.php?f=54&t=164&p=994&hilit=ad ... tines#p994 for using both. Dmitry retains the control over his subsystem.
- Helmut
Dmitry Dagaev
Posts: 68
Joined: Wed Mar 29, 2017 3:58 pm

Re: Co_Routines Support for Oberon

Post by Dmitry Dagaev »

Helmut wrote: What is the different between Oberon-0 style and BlackBox style inside subsystem Co_?
Co_ uses Oberon-0 style

Code: Select all

	PROCEDURE Do (t: Ct.Task);
		VAR trav: Traverse;
	BEGIN
		trav := t(Traverse);
		NextTreeLeaves(trav, trav.tree);
		Co.Stop
	END Do;

Code: Select all

		r1.Start(r1); r2.Start(r2);
		WHILE ~r1.eor & ~r2.eor & same DO
			r1.Transfer(r1);
			r2.Transfer(r2);
			same := (r1.leaf.name$ = r2.leaf.name$)
		END;
		IF ~r1.eor OR ~r2.eor THEN same := FALSE END;
In BlackBox style I can rewrite it like

Code: Select all

	PROCEDURE (trav: Traverse) Do ;
	BEGIN
		NextTreeLeaves(trav, trav.tree);
		Co.Stop
	END Do;

Code: Select all

		r1.Start; r2.Start;
		WHILE ~r1.eor & ~r2.eor & same DO
			r1.Transfer;
			r2.Transfer;
			same := (r1.leaf.name$ = r2.leaf.name$)
		END;
		IF ~r1.eor OR ~r2.eor THEN same := FALSE END;
Co_Routines are tracking Kernel updates.
Josef Templ
Posts: 262
Joined: Tue Sep 17, 2013 6:50 am

Re: Co_Routines Support for Oberon

Post by Josef Templ »

Dmitry Dagaev wrote:More precise measurements with background tasks.

I've compared calculation time for ObxCoroutines.RunPrimes and Co_ObxActions.StartPrimes.
Initial conditions:
1. modified Co_ObxActions to set Co.Yield in the same place, as in ObxCoroutines.
2. excluded time consuming primes logging calls.
3. set 100% CPU usage threshold for Co_ scheduler

Code: Select all

		s := Ct.scheduler;
		p.interval := 50;  (* 50 ms *)
		p.load_pct := 100;  (* 100% cpu *)
		s.SetParams(s, p);
Called parameters:
limit = 10000000

The results are (with 10% inaccuracy):
  • 37.80 sec - ObxCoroutines
  • 5.61 sec - Co_ObxActions
  • 18.1 sec - Co_ObxActions with default parameters (usage for bg tasks is 40% limited)
  • 5.41 sec - Co_ObxActions as foreground task (Co.Yield excluded)
My latest build delivers a CPU utilization of close to 100% for both server mode and normal mode.
Previously it was close to 100% only when operating in server mode.
The Primes example should benefit from this change.

- Josef
Josef Templ
Posts: 262
Joined: Tue Sep 17, 2013 6:50 am

Re: Co_Routines Support for Oberon

Post by Josef Templ »

Robert wrote:I have not had the time (and there are probably other reasons) to follow this discussion carefully, so I apologise if my remarks seem rather trivial.
Some time ago I had an algorithmic problem (a bit similar to the same frimge question) and found, on the internet, a solution described in terms of Python Iterators with Yields (if I remember correctly). I thought: "That's neat, but I can't see how to do that in Component Pascal". But it was apparent that a prettly simple understanding of a couple of language (Python) keywords gave access to a significant capability; the whole thing was not too scary.

This discussion is really quite scary for a potential very infrequent user of coroutines - I've only actively wanted them once in a lifetime! The Co package is 2 MByte (compressed); that alone makes one feel that it is aimed at the expert user who can cope with (and needs) very many specialised options.

Are we going in the direction of having two (or three if we think of Ivan's suggestions as an alternative) overlapping packages in both CPC & the Center distribution? That, I think, would make the subject even more inacessible for the new or casual user.

Is there a balance to be struck between the needs of the expert and the wishes of the beginner? Are we heading towards it? Or is such a compromise the worst of all worlds, and we should choose a target audience (experts, I guess) and pitch the development to their needs?

And what about the overlap between the 2014 Co_ subsystem and the 2017 Center proposals? Is it large overlap? Is it a good thing? Is it a bad thing?
The center's Coroutines module is designed in such a way that it serves both, experts and beginners.
Actually, there is not much difference between experts and beginners in this case.
The difference in the design of a coroutine package is more if it aims to be a general purpose tool
or a special purpose tool. The center's Coroutines are general purpose while the Co_ package,
as far as I understand it, is a special purpose tool. It aims specifically at data flow programming,
or however that may be called. This is a very narrow focus far from being general purpose.
It is easy to construct perfectly meaningful applications that cannot be implemented with Co_.
Nevertheless, some people may find it useful if their application fits with the supported pattern(s).

Robert, if you want to get started with coroutines, I would recommend to start with a plain Coroutines.Coroutine
example. Here you see the basic mechanism without any bells and whistles. ObxCoroutines contains
such an example. The next step would be to look at the Iterator example (SameFringe) and then look
at the Task example (Primes) or vice verse. Compare the Primes example with the similar example in ObxActions.

- Josef
Dmitry Dagaev
Posts: 68
Joined: Wed Mar 29, 2017 3:58 pm

Re: Co_Routines Support for Oberon

Post by Dmitry Dagaev »

Here is new Co_ version, updated for the latest build http://blackboxframework.org/unstable/i ... a1.849.zip.
It introduces Blackbox-style interface. The simplest example Co_ObxSimple is as following

Code: Select all

	IMPORT Co := Co_Routines, Log;
	
	TYPE
		Generator = POINTER TO GeneratorDesc;
		GeneratorDesc = RECORD (Co.CoroutineDesc)
			v: INTEGER;
		END;
		

	PROCEDURE (g: Generator) Do;
	BEGIN
		g.v := 1; Co.Yield;
		g.v := 2; Co.Yield;
		g.v := 3; Co.Stop;
	END Do;
	
	PROCEDURE Run*;
		VAR g: Generator;
	BEGIN
		NEW(g);
		g.Start;
		WHILE ~g.eor DO
			g.Transfer;
			Log.String("Gen"); Log.Int(g.v); Log.Ln
		END;
		Log.String("End");Log.Ln;
	END Run;
Attachments
Co_.zip
New Co_ version
(88.8 KiB) Downloaded 655 times
Dmitry Dagaev
Posts: 68
Joined: Wed Mar 29, 2017 3:58 pm

Re: Co_Routines Support for Oberon

Post by Dmitry Dagaev »

Josef Templ wrote: It is easy to construct perfectly meaningful applications that cannot be implemented with Co_.
Can you, please, show any example?
Post Reply