Re: [Vala] Further speculations on couroutines, generators and threads : Emulating Go's goroutines and channels in Vala

2011-07-14 Thread Serge Hulne
Good question, I don't know !

Let's ask the creator of the language himself (Jütrg Billete)

Serge.

On Wed, Jul 13, 2011 at 9:17 PM, august aug...@alien.mur.at wrote:


 I've been following this thread with interest.   I also find the
 documentation about async methods in vala to be a little thin.  For
 example, in the tutorial, the first line of description says:


With asynchronous methods it is possible to do programming without
any blocking.

 The following examples in the tutorial  are much more enlightening...so
 it's not that bad.   But, maybe it could be improved.


 I always thought async methods:
a) are always single threaded
b) uses the glib runtime scheduler to simulate
multi-processes
c) cannot take advantage of multi-core or multi-processor
computers

 Is that correct?


 Also, are there any plans to ease multi-core development in Vala?


 thanks, best -august.


  Actually, this is Luca's code (the coroutine-based generator).
 
  (I am the guilty party to blame for the naive idea to try to add threads
 to
  it : I had the Goroutine/channel concept of Go in mind and was trying to
  emulate it by attempting to combine Luca's generator with threads).
 
  :)
 
  Serge.
 
 
 
  On Wed, Jul 13, 2011 at 3:02 PM, Jim Peters j...@uazu.net wrote:
 
   Serge Hulne wrote:
Here is a further development of the idea of Luca Bruno about a Vala
implementation for Generators:
   
Simulating  Go's goroutines and channels in Vala:
   
Basically the idea is to start as many threads as needed (which play
 the
role of Go' goroutines) and to recuperate their output from a
 Generator
(which plays the role of the Go channel form which the result from
 a
   given
thread can be pulled):
  
   To clarify after all the confusion (partly my fault -- sorry):
  
   - Luco's Generator doesn't need threads, and it doesn't need a main
loop either, even though it is using 'async'
  
   - The whole thing runs in a single thread
  
   A few thoughts:
  
   - 'async' is really powerful in Vala, but also quite hard to
understand.  (I wish I could find a high-level design document
explaining async in GIO.)
  
   - Its implementation of coroutines doesn't require another stack, it
holds its state in a private data structure.  When it does a 'yield'
it returns to the caller, and when it is next given control, it
resumes the previous point of execution using a switch and 'goto'.
  
   - Probably it could all go a lot faster if less housekeeping was going
on, but I haven't seen Go's implementation either, so who knows how
it compares.  Anyway, Vala always puts functionality first and
optimisation second, which suits people who want to get the job done
now instead of waiting for the ultimate language to arrive, so that
seems okay.
  
   Attached is a version of Serge's code with all the thread stuff cut
   out, which still works.
  
   Jim
  
   /
   using Posix;
  
   abstract class GeneratorG {
  private bool consumed;
  private unowned G value;
  private SourceFunc callback;
  
  public Generator () {
  helper ();
  }
  
  private async void helper () {
  yield generate ();
  consumed = true;
  }
  
  protected abstract async void generate ();
  
  protected async void feed (G value) {
  this.value = value;
  this.callback = feed.callback;
  yield;
  }
  
  public bool next () {
  return !consumed;
  }
  
  public G get () {
  var result = value;
  callback ();
  return result;
  }
  
  public GeneratorG iterator () {
  return this;
  }
   }
  
   class IntGenerator : Generatorint {
  protected override async void generate () {
  for (int i=0; i  10; i++) {
   if (i%2 ==0) yield feed (i);
  }
  }
   }
  
   class IntGenerator_1 : Generatorint {
  protected override async void generate () {
  for (int i=0; i  10; i++) {
   if (i%2 !=0) yield feed (i);
  }
  }
   }
  
   int main(string[] args) {
  
  var gen = new IntGenerator();
  var gen_1 = new IntGenerator_1();
  
  print(\n\nResults computed in first generator\n);
  
  var i=0;
  foreach (var item in gen) {
  if (i10) Posix.stdout.printf(%i\n, item);
  i++;
  }
  
   print(\n\nResults computed in the second generator\n\n);
  
  i=0;
  foreach (var item in gen_1) {
  if (i10) Posix.stdout.printf(%i\n, item);
  i++;
  }
  
  return 0;
   }
  
   /
  
   --
Jim Peters  (_)/=\~/_(_) j...@uazu.net
(_)  /=\  ~/_  (_)
Uazú  (_)/=\~/_(_)http://
in Peru(_)  

Re: [Vala] Further speculations on couroutines, generators and threads : Emulating Go's goroutines and channels in Vala

2011-07-14 Thread Alexandre Rosenfeld
On Wed, Jul 13, 2011 at 15:17, august aug...@alien.mur.at wrote:

With asynchronous methods it is possible to do programming without
any blocking.

 The following examples in the tutorial  are much more enlightening...so
 it's not that bad.   But, maybe it could be improved.


Async methods were created primarily for GIO to do non-blocking IO. Doing IO
usually blocks the application and so freezes the UI, so the GLib answer is
to provide callbacks to be called when the IO is done and the program can
keep executing while IO is done in the background (note here that background
does not necessarily mean another thread, the IO can be done by the kernel
and notify the process when it's complete).


 I always thought async methods:
a) are always single threaded
b) uses the glib runtime scheduler to simulate
multi-processes
c) cannot take advantage of multi-core or multi-processor
computers


Async methods have nothing to do with threads, so none of these points are
valid. However, what async methods allow is to stop the processing of a
function in the middle and resume it after the async method returns, by the
means of the callbacks. So, what the async method can do is spawn a thread
to do background processing and later call the callback to resume the
operation of the method that called it.
Which means async methods can be just as blocking as any other method if it
does sequential processing and at the end calls the callback. But also means
it can be designed to use any other way to provide background processing
(including threads) without blocking the main program (especially the UI)
and thus can take advantage of multiple cores.

At least this is what I understood so far about async methods, please let me
know if any of this is wrong.

Regards,
Alexandre
___
vala-list mailing list
vala-list@gnome.org
http://mail.gnome.org/mailman/listinfo/vala-list


Re: [Vala] Further speculations on couroutines, generators and threads : Emulating Go's goroutines and channels in Vala

2011-07-13 Thread Jim Peters
Serge Hulne wrote:
 Here is a further development of the idea of Luca Bruno about a Vala
 implementation for Generators:
 
 Simulating  Go's goroutines and channels in Vala:
 
 Basically the idea is to start as many threads as needed (which play the
 role of Go' goroutines) and to recuperate their output from a Generator
 (which plays the role of the Go channel form which the result from a given
 thread can be pulled):

To clarify after all the confusion (partly my fault -- sorry):

- Luco's Generator doesn't need threads, and it doesn't need a main
  loop either, even though it is using 'async'

- The whole thing runs in a single thread

A few thoughts:

- 'async' is really powerful in Vala, but also quite hard to
  understand.  (I wish I could find a high-level design document
  explaining async in GIO.)

- Its implementation of coroutines doesn't require another stack, it
  holds its state in a private data structure.  When it does a 'yield'
  it returns to the caller, and when it is next given control, it
  resumes the previous point of execution using a switch and 'goto'.

- Probably it could all go a lot faster if less housekeeping was going
  on, but I haven't seen Go's implementation either, so who knows how
  it compares.  Anyway, Vala always puts functionality first and
  optimisation second, which suits people who want to get the job done
  now instead of waiting for the ultimate language to arrive, so that
  seems okay.

Attached is a version of Serge's code with all the thread stuff cut
out, which still works.

Jim

/
using Posix;

abstract class GeneratorG {
private bool consumed;
private unowned G value;
private SourceFunc callback;

public Generator () {
helper ();
}

private async void helper () {
yield generate ();
consumed = true;
}

protected abstract async void generate ();

protected async void feed (G value) {
this.value = value;
this.callback = feed.callback;
yield;
}

public bool next () {
return !consumed;
}

public G get () {
var result = value;
callback ();
return result;
}

public GeneratorG iterator () {
return this;
}
}

class IntGenerator : Generatorint {
protected override async void generate () {
for (int i=0; i  10; i++) {
 if (i%2 ==0) yield feed (i);
}
}
}

class IntGenerator_1 : Generatorint {
protected override async void generate () {
for (int i=0; i  10; i++) {
 if (i%2 !=0) yield feed (i);
}
}
}

int main(string[] args) {

var gen = new IntGenerator();
var gen_1 = new IntGenerator_1();

print(\n\nResults computed in first generator\n);

var i=0;
foreach (var item in gen) {
if (i10) Posix.stdout.printf(%i\n, item);
i++;
}

print(\n\nResults computed in the second generator\n\n);

i=0;
foreach (var item in gen_1) {
if (i10) Posix.stdout.printf(%i\n, item);
i++;
}

return 0;
}

/

-- 
 Jim Peters  (_)/=\~/_(_) j...@uazu.net
  (_)  /=\  ~/_  (_)
 Uazú  (_)/=\~/_(_)http://
 in Peru(_)  /=\  ~/_  (_)uazu.net
___
vala-list mailing list
vala-list@gnome.org
http://mail.gnome.org/mailman/listinfo/vala-list


Re: [Vala] Further speculations on couroutines, generators and threads : Emulating Go's goroutines and channels in Vala

2011-07-13 Thread Serge Hulne
Actually, this is Luca's code (the coroutine-based generator).

(I am the guilty party to blame for the naive idea to try to add threads to
it : I had the Goroutine/channel concept of Go in mind and was trying to
emulate it by attempting to combine Luca's generator with threads).

:)

Serge.



On Wed, Jul 13, 2011 at 3:02 PM, Jim Peters j...@uazu.net wrote:

 Serge Hulne wrote:
  Here is a further development of the idea of Luca Bruno about a Vala
  implementation for Generators:
 
  Simulating  Go's goroutines and channels in Vala:
 
  Basically the idea is to start as many threads as needed (which play the
  role of Go' goroutines) and to recuperate their output from a Generator
  (which plays the role of the Go channel form which the result from a
 given
  thread can be pulled):

 To clarify after all the confusion (partly my fault -- sorry):

 - Luco's Generator doesn't need threads, and it doesn't need a main
  loop either, even though it is using 'async'

 - The whole thing runs in a single thread

 A few thoughts:

 - 'async' is really powerful in Vala, but also quite hard to
  understand.  (I wish I could find a high-level design document
  explaining async in GIO.)

 - Its implementation of coroutines doesn't require another stack, it
  holds its state in a private data structure.  When it does a 'yield'
  it returns to the caller, and when it is next given control, it
  resumes the previous point of execution using a switch and 'goto'.

 - Probably it could all go a lot faster if less housekeeping was going
  on, but I haven't seen Go's implementation either, so who knows how
  it compares.  Anyway, Vala always puts functionality first and
  optimisation second, which suits people who want to get the job done
  now instead of waiting for the ultimate language to arrive, so that
  seems okay.

 Attached is a version of Serge's code with all the thread stuff cut
 out, which still works.

 Jim

 /
 using Posix;

 abstract class GeneratorG {
private bool consumed;
private unowned G value;
private SourceFunc callback;

public Generator () {
helper ();
}

private async void helper () {
yield generate ();
consumed = true;
}

protected abstract async void generate ();

protected async void feed (G value) {
this.value = value;
this.callback = feed.callback;
yield;
}

public bool next () {
return !consumed;
}

public G get () {
var result = value;
callback ();
return result;
}

public GeneratorG iterator () {
return this;
}
 }

 class IntGenerator : Generatorint {
protected override async void generate () {
for (int i=0; i  10; i++) {
 if (i%2 ==0) yield feed (i);
}
}
 }

 class IntGenerator_1 : Generatorint {
protected override async void generate () {
for (int i=0; i  10; i++) {
 if (i%2 !=0) yield feed (i);
}
}
 }

 int main(string[] args) {

var gen = new IntGenerator();
var gen_1 = new IntGenerator_1();

print(\n\nResults computed in first generator\n);

var i=0;
foreach (var item in gen) {
if (i10) Posix.stdout.printf(%i\n, item);
i++;
}

 print(\n\nResults computed in the second generator\n\n);

i=0;
foreach (var item in gen_1) {
if (i10) Posix.stdout.printf(%i\n, item);
i++;
}

return 0;
 }

 /

 --
  Jim Peters  (_)/=\~/_(_) j...@uazu.net
  (_)  /=\  ~/_  (_)
  Uazú  (_)/=\~/_(_)http://
  in Peru(_)  /=\  ~/_  (_)uazu.net

___
vala-list mailing list
vala-list@gnome.org
http://mail.gnome.org/mailman/listinfo/vala-list


Re: [Vala] Further speculations on couroutines, generators and threads : Emulating Go's goroutines and channels in Vala

2011-07-13 Thread august

I've been following this thread with interest.   I also find the
documentation about async methods in vala to be a little thin.  For
example, in the tutorial, the first line of description says:


With asynchronous methods it is possible to do programming without
any blocking.

The following examples in the tutorial  are much more enlightening...so
it's not that bad.   But, maybe it could be improved.


I always thought async methods:
a) are always single threaded
b) uses the glib runtime scheduler to simulate 
multi-processes
c) cannot take advantage of multi-core or multi-processor
computers

Is that correct?


Also, are there any plans to ease multi-core development in Vala?


thanks, best -august.


 Actually, this is Luca's code (the coroutine-based generator).
 
 (I am the guilty party to blame for the naive idea to try to add threads to
 it : I had the Goroutine/channel concept of Go in mind and was trying to
 emulate it by attempting to combine Luca's generator with threads).
 
 :)
 
 Serge.
 
 
 
 On Wed, Jul 13, 2011 at 3:02 PM, Jim Peters j...@uazu.net wrote:
 
  Serge Hulne wrote:
   Here is a further development of the idea of Luca Bruno about a Vala
   implementation for Generators:
  
   Simulating  Go's goroutines and channels in Vala:
  
   Basically the idea is to start as many threads as needed (which play the
   role of Go' goroutines) and to recuperate their output from a Generator
   (which plays the role of the Go channel form which the result from a
  given
   thread can be pulled):
 
  To clarify after all the confusion (partly my fault -- sorry):
 
  - Luco's Generator doesn't need threads, and it doesn't need a main
   loop either, even though it is using 'async'
 
  - The whole thing runs in a single thread
 
  A few thoughts:
 
  - 'async' is really powerful in Vala, but also quite hard to
   understand.  (I wish I could find a high-level design document
   explaining async in GIO.)
 
  - Its implementation of coroutines doesn't require another stack, it
   holds its state in a private data structure.  When it does a 'yield'
   it returns to the caller, and when it is next given control, it
   resumes the previous point of execution using a switch and 'goto'.
 
  - Probably it could all go a lot faster if less housekeeping was going
   on, but I haven't seen Go's implementation either, so who knows how
   it compares.  Anyway, Vala always puts functionality first and
   optimisation second, which suits people who want to get the job done
   now instead of waiting for the ultimate language to arrive, so that
   seems okay.
 
  Attached is a version of Serge's code with all the thread stuff cut
  out, which still works.
 
  Jim
 
  /
  using Posix;
 
  abstract class GeneratorG {
 private bool consumed;
 private unowned G value;
 private SourceFunc callback;
 
 public Generator () {
 helper ();
 }
 
 private async void helper () {
 yield generate ();
 consumed = true;
 }
 
 protected abstract async void generate ();
 
 protected async void feed (G value) {
 this.value = value;
 this.callback = feed.callback;
 yield;
 }
 
 public bool next () {
 return !consumed;
 }
 
 public G get () {
 var result = value;
 callback ();
 return result;
 }
 
 public GeneratorG iterator () {
 return this;
 }
  }
 
  class IntGenerator : Generatorint {
 protected override async void generate () {
 for (int i=0; i  10; i++) {
  if (i%2 ==0) yield feed (i);
 }
 }
  }
 
  class IntGenerator_1 : Generatorint {
 protected override async void generate () {
 for (int i=0; i  10; i++) {
  if (i%2 !=0) yield feed (i);
 }
 }
  }
 
  int main(string[] args) {
 
 var gen = new IntGenerator();
 var gen_1 = new IntGenerator_1();
 
 print(\n\nResults computed in first generator\n);
 
 var i=0;
 foreach (var item in gen) {
 if (i10) Posix.stdout.printf(%i\n, item);
 i++;
 }
 
  print(\n\nResults computed in the second generator\n\n);
 
 i=0;
 foreach (var item in gen_1) {
 if (i10) Posix.stdout.printf(%i\n, item);
 i++;
 }
 
 return 0;
  }
 
  /
 
  --
   Jim Peters  (_)/=\~/_(_) j...@uazu.net
   (_)  /=\  ~/_  (_)
   Uazú  (_)/=\~/_(_)http://
   in Peru(_)  /=\  ~/_  (_)uazu.net
 

 ___
 vala-list mailing list
 vala-list@gnome.org
 http://mail.gnome.org/mailman/listinfo/vala-list


-- 
---
http://aug.ment.org



signature.asc
Description: Digital signature

Re: [Vala] Further speculations on couroutines, generators and threads : Emulating Go's goroutines and channels in Vala

2011-07-12 Thread Serge Hulne
Obviously, if the code proposed by Luca was stored separately in its own
file (or in)  library then all one would have to to to use use this
goroutine/channnels/-ike construct boils down to:

/
using Posix;

IntGeneratorgen;
IntGenerator_1  gen_1;

void* thread_func() {
//Posix.stdout.printf(Thread running.\n);
gen = new IntGenerator();
return null;
}

void* thread_func_1() {
//Posix.stdout.printf(Thread running.\n);
gen_1 = new IntGenerator_1();
return null;
}


int main(string[] args) {

if (!Thread.supported()) {
Posix.stderr.printf(Cannot run without threads.\n);
return 1;
}

try {
unowned Threadvoid* thread = Thread.createvoid*(thread_func,
true);
thread.join();

unowned Threadvoid* thread_1 = Thread.createvoid*(thread_func_1,
true);
thread_1.join();

} catch (ThreadError e) {
return 1;
}

print(\n\nResults computed in first thread\n);

var i=0;
foreach (var item in gen) {
if (i10) Posix.stdout.printf(%i\n, item);
i++;
}

print(\n\nResults computed in the second thread\n\n);

i=0;
foreach (var item in gen_1) {
if (i10) Posix.stdout.printf(%i\n, item);
i++;
}


return 0;
}
/




On Tue, July 12, 2011 at 5:55 AM, Serge Hulne serge.hu...@gmail.com wrote:

 Here is a further development of the idea of Luca Bruno about a Vala
 implementation for Generators:

 Simulating  Go's goroutines and channels in Vala:

 Basically the idea is to start as many threads as needed (which play the
 role of Go' goroutines) and to recuperate their output from a Generator
 (which plays the role of the Go channel form which the result from a given
 thread can be pulled):

 See code hereunder,
 Serge.



 /
 using Posix;

 abstract class GeneratorG {
 private bool consumed;
 private unowned G value;
 private SourceFunc callback;

 public Generator () {
 helper ();
 }

 private async void helper () {
 yield generate ();
 consumed = true;
 }

 protected abstract async void generate ();

 protected async void feed (G value) {
 this.value = value;
 this.callback = feed.callback;
 yield;
 }

 public bool next () {
 return !consumed;
 }

 public G get () {
 var result = value;
 callback ();
 return result;
 }

 public GeneratorG iterator () {
 return this;
 }
 }



 class IntGenerator : Generatorint {
 protected override async void generate () {
 for (int i=0; i  10; i++) {
  if (i%2 ==0) yield feed (i);
 }
 }
 }

 class IntGenerator_1 : Generatorint {
 protected override async void generate () {
 for (int i=0; i  10; i++) {
  if (i%2 !=0) yield feed (i);
 }
 }
 }

 IntGeneratorgen;
 IntGenerator_1  gen_1;

 void* thread_func() {
 //Posix.stdout.printf(Thread running.\n);
 gen = new IntGenerator();
 return null;
 }

 void* thread_func_1() {
 //Posix.stdout.printf(Thread running.\n);
 gen_1 = new IntGenerator_1();
 return null;
 }


 int main(string[] args) {

 if (!Thread.supported()) {
 Posix.stderr.printf(Cannot run without threads.\n);
 return 1;
 }

 try {
 unowned Threadvoid* thread = Thread.createvoid*(thread_func,
 true);
 thread.join();

 unowned Threadvoid* thread_1 =
 Thread.createvoid*(thread_func_1, true);
 thread_1.join();

 } catch (ThreadError e) {
 return 1;
 }

 print(\n\nResults computed in first thread\n);

 var i=0;
 foreach (var item in gen) {
 if (i10) Posix.stdout.printf(%i\n, item);
 i++;
 }

 print(\n\nResults computed in the second thread\n\n);

 i=0;
 foreach (var item in gen_1) {
 if (i10) Posix.stdout.printf(%i\n, item);
 i++;
 }


 return 0;
 }

 /

___
vala-list mailing list
vala-list@gnome.org
http://mail.gnome.org/mailman/listinfo/vala-list


Re: [Vala] Further speculations on couroutines, generators and threads : Emulating Go's goroutines and channels in Vala

2011-07-12 Thread Jim Peters
Serge Hulne wrote:
 Here is a further development of the idea of Luca Bruno about a Vala
 implementation for Generators:
 
 Simulating  Go's goroutines and channels in Vala:
 
 Basically the idea is to start as many threads as needed (which play the
 role of Go' goroutines) and to recuperate their output from a Generator
 (which plays the role of the Go channel form which the result from a given
 thread can be pulled):

Threads are very heavy compared to an optimised implementation of
'goroutines' or whatever.  Certainly you can emulate them but it's not
going to be an efficient way of implementing algorithms unless someone
puts in the work to make it efficient under the hood.

If convenience matters more than efficiency, then no problem.

Jim

-- 
 Jim Peters  (_)/=\~/_(_) j...@uazu.net
  (_)  /=\  ~/_  (_)
 Uazú  (_)/=\~/_(_)http://
 in Peru(_)  /=\  ~/_  (_)uazu.net
___
vala-list mailing list
vala-list@gnome.org
http://mail.gnome.org/mailman/listinfo/vala-list


Re: [Vala] Further speculations on couroutines, generators and threads : Emulating Go's goroutines and channels in Vala

2011-07-12 Thread Luca Bruno
On Tue, Jul 12, 2011 at 07:43:14AM -0500, Jim Peters wrote:
 Serge Hulne wrote:
  Here is a further development of the idea of Luca Bruno about a Vala
  implementation for Generators:
  
  Simulating  Go's goroutines and channels in Vala:
  
  Basically the idea is to start as many threads as needed (which play the
  role of Go' goroutines) and to recuperate their output from a Generator
  (which plays the role of the Go channel form which the result from a given
  thread can be pulled):
 
 Threads are very heavy compared to an optimised implementation of
 'goroutines' or whatever.  Certainly you can emulate them but it's not
 going to be an efficient way of implementing algorithms unless someone
 puts in the work to make it efficient under the hood.
 
 If convenience matters more than efficiency, then no problem.

Do you have any benchmark? I wouldn't say that loudly in general.

-- 
http://www.debian.org - The Universal Operating System
___
vala-list mailing list
vala-list@gnome.org
http://mail.gnome.org/mailman/listinfo/vala-list


Re: [Vala] Further speculations on couroutines, generators and threads : Emulating Go's goroutines and channels in Vala

2011-07-12 Thread Serge Hulne
Absolutely correct !

Hence the term speculation

Moreover, if efficiency was paramount, the whole construct would have to be
implemented at lower level (in C not in Vala).

Another reason why these speculations cannot possibly add anything
performance-wise is that I don't think (I might be wrong) that Vala can be
tailored specifically for a given multi-core architecture. In this case,
using threads can be convenient, but it will not process tasks in parallel,
therefore threads can only slow down the execution of an application.

Last but not least goroutines are indeed more lightweight than threads (they
use threads but they are not threads).

So basically it was just for convenience (and for fun) !

Serge.





On Tue, Jul 12, 2011 at 2:43 PM, Jim Peters j...@uazu.net wrote:

 Serge Hulne wrote:
  Here is a further development of the idea of Luca Bruno about a Vala
  implementation for Generators:
 
  Simulating  Go's goroutines and channels in Vala:
 
  Basically the idea is to start as many threads as needed (which play the
  role of Go' goroutines) and to recuperate their output from a Generator
  (which plays the role of the Go channel form which the result from a
 given
  thread can be pulled):

 Threads are very heavy compared to an optimised implementation of
 'goroutines' or whatever.  Certainly you can emulate them but it's not
 going to be an efficient way of implementing algorithms unless someone
 puts in the work to make it efficient under the hood.

 If convenience matters more than efficiency, then no problem.

 Jim

 --
  Jim Peters  (_)/=\~/_(_) j...@uazu.net
  (_)  /=\  ~/_  (_)
  Uazú  (_)/=\~/_(_)http://
  in Peru(_)  /=\  ~/_  (_)uazu.net

___
vala-list mailing list
vala-list@gnome.org
http://mail.gnome.org/mailman/listinfo/vala-list


Re: [Vala] Further speculations on couroutines, generators and threads : Emulating Go's goroutines and channels in Vala

2011-07-12 Thread Alexandre Rosenfeld
On Tue, Jul 12, 2011 at 11:11, Serge Hulne serge.hu...@gmail.com wrote:

 Another reason why these speculations cannot possibly add anything
 performance-wise is that I don't think (I might be wrong) that Vala can be
 tailored specifically for a given multi-core architecture. In this case,
 using threads can be convenient, but it will not process tasks in parallel,
 therefore threads can only slow down the execution of an application.


Vala threads are based on GLib threads, so they do scale to multicore
systems and they do process in parallel. Contrary to a few other languages,
Vala does not emulate threads, it uses the system threads (with all the
benefits and problems of that).
But pay attention that if your application is not designed for concurrent
processing, it won't matter. For instance, you can block one thread waiting
for the other to finish processing or to free some resource, then you are
just doing sequential processing anyway.

*Alexandre Rosenfeld*
___
vala-list mailing list
vala-list@gnome.org
http://mail.gnome.org/mailman/listinfo/vala-list


Re: [Vala] Further speculations on couroutines, generators and threads : Emulating Go's goroutines and channels in Vala

2011-07-12 Thread Jim Peters
Luca Bruno wrote:
  Threads are very heavy compared to an optimised implementation of
  'goroutines' or whatever.  Certainly you can emulate them but it's not
  going to be an efficient way of implementing algorithms unless someone
  puts in the work to make it efficient under the hood.
  
  If convenience matters more than efficiency, then no problem.
 
 Do you have any benchmark? I wouldn't say that loudly in general.

No, I don't have a benchmark, but a Thread is actually a kernel
process on Linux, whereas a goroutine could be just an allocated
mini-stack of 100 bytes (assuming enough static analysis to figure out
required stack depth) and some housekeeping structures.  Switching
between threads means waiting for the Linux kernel to schedule it.
Switching to/from a go/coroutine could be a longjmp (having read some
of the Pth implementation stuff).

To me it seems that they would not be comparable in efficiency.

I think that the idea of goroutines is that they can be used
everywhere in the code, just like an 'if' or a 'for'.  So there could
be 100s of them active.  If they only need 100-200 bytes each, that is
manageable.  If they require an entire kernel process for each one,
then it does not seem like a good approach.

I guess if we're just talking about one or two extra threads running
at the top level of the application, then I agree, that is fine.  But
using them as a fundamental control-flow structure within the language
needs a more optimised implementation.

In this case we're talking about an Iterator.  A traditional
non-coroutine implementation of an Iterator would hold state in the
Iterator object and generate new objects to return one by one on
demand, implemented with an internal generate_next() call or similar.
This will run in a single thread.  A co-routine or generator type
implementation turns the code inside out, and holds state on its own
private stack (i.e. local variables) instead of inside the Iterator
object.  If implemented as a coroutine the iteration will also run
inside a single thread, and the equivalent of the generate_next() call
is a longjmp switch to the coroutine and a longjmp back.  This is
comparable to the non-coroutine implementation.  However, if the
coroutine is running in a separate thread, then we require the kernel
to schedule a context switch.  This HAS to be slower -- at least
that's how it seems to me.

Maybe this could be made more workable using 'Pth' instead of kernel
threads, or by using the async stuff already in Vala.  (Sorry, I'm not
up to speed on that yet.)

Jim

-- 
 Jim Peters  (_)/=\~/_(_) j...@uazu.net
  (_)  /=\  ~/_  (_)
 Uazú  (_)/=\~/_(_)http://
 in Peru(_)  /=\  ~/_  (_)uazu.net
___
vala-list mailing list
vala-list@gnome.org
http://mail.gnome.org/mailman/listinfo/vala-list


Re: [Vala] Further speculations on couroutines, generators and threads : Emulating Go's goroutines and channels in Vala

2011-07-12 Thread Luca Bruno
On Tue, Jul 12, 2011 at 12:04:13PM -0500, Jim Peters wrote:
 Luca Bruno wrote:
   Threads are very heavy compared to an optimised implementation of
   'goroutines' or whatever.  Certainly you can emulate them but it's not
   going to be an efficient way of implementing algorithms unless someone
   puts in the work to make it efficient under the hood.
   
   If convenience matters more than efficiency, then no problem.
  
  Do you have any benchmark? I wouldn't say that loudly in general.
 
 No, I don't have a benchmark, but a Thread is actually a kernel
 process on Linux, whereas a goroutine could be just an allocated
 mini-stack of 100 bytes (assuming enough static analysis to figure out
 required stack depth) and some housekeeping structures.  Switching
 between threads means waiting for the Linux kernel to schedule it.
 Switching to/from a go/coroutine could be a longjmp (having read some
 of the Pth implementation stuff).
 
 To me it seems that they would not be comparable in efficiency.

Threads are allocated on multiple cores nowadays and you can use lock-free
data structures when possible. Still you didn't provide any benchmark,
only thoughts.

-- 
http://www.debian.org - The Universal Operating System
___
vala-list mailing list
vala-list@gnome.org
http://mail.gnome.org/mailman/listinfo/vala-list


Re: [Vala] Further speculations on couroutines, generators and threads : Emulating Go's goroutines and channels in Vala

2011-07-12 Thread Jim Peters
Christian Siefkes wrote:
 Iterators already exist in Vala, so why not just use them?
 (I didn't look in detail at the examples for couroutines and generators, so
 if I missed something obvious, sorry.)

The original poster wanted to write his iterator in the style of Go,
i.e. with a coroutine style.

Jim

-- 
 Jim Peters  (_)/=\~/_(_) j...@uazu.net
  (_)  /=\  ~/_  (_)
 Uazú  (_)/=\~/_(_)http://
 in Peru(_)  /=\  ~/_  (_)uazu.net
___
vala-list mailing list
vala-list@gnome.org
http://mail.gnome.org/mailman/listinfo/vala-list


Re: [Vala] Further speculations on couroutines, generators and threads : Emulating Go's goroutines and channels in Vala

2011-07-12 Thread Jim Peters
Luca Bruno wrote:
  No, I don't have a benchmark, but a Thread is actually a kernel
  process on Linux, whereas a goroutine could be just an allocated
  mini-stack of 100 bytes (assuming enough static analysis to figure out
  required stack depth) and some housekeeping structures.  Switching
  between threads means waiting for the Linux kernel to schedule it.
  Switching to/from a go/coroutine could be a longjmp (having read some
  of the Pth implementation stuff).
  
  To me it seems that they would not be comparable in efficiency.
 
 Threads are allocated on multiple cores nowadays and you can use lock-free
 data structures when possible. Still you didn't provide any benchmark,
 only thoughts.

We are both putting forward only thoughts.

To prove my point I will have to implement simple coroutines in Vala
using low-level C stuff, i.e. setcontext/makecontext/etc.  I guess a
Coroutine class could be useful for something someday.  Give me a
moment ...

Jim

-- 
 Jim Peters  (_)/=\~/_(_) j...@uazu.net
  (_)  /=\  ~/_  (_)
 Uazú  (_)/=\~/_(_)http://
 in Peru(_)  /=\  ~/_  (_)uazu.net
___
vala-list mailing list
vala-list@gnome.org
http://mail.gnome.org/mailman/listinfo/vala-list


[Vala] Further speculations on couroutines, generators and threads : Emulating Go's goroutines and channels in Vala

2011-07-11 Thread Serge Hulne
Here is a further development of the idea of Luca Bruno about a Vala
implementation for Generators:

Simulating  Go's goroutines and channels in Vala:

Basically the idea is to start as many threads as needed (which play the
role of Go' goroutines) and to recuperate their output from a Generator
(which plays the role of the Go channel form which the result from a given
thread can be pulled):

See code hereunder,
Serge.



/
using Posix;

abstract class GeneratorG {
private bool consumed;
private unowned G value;
private SourceFunc callback;

public Generator () {
helper ();
}

private async void helper () {
yield generate ();
consumed = true;
}

protected abstract async void generate ();

protected async void feed (G value) {
this.value = value;
this.callback = feed.callback;
yield;
}

public bool next () {
return !consumed;
}

public G get () {
var result = value;
callback ();
return result;
}

public GeneratorG iterator () {
return this;
}
}



class IntGenerator : Generatorint {
protected override async void generate () {
for (int i=0; i  10; i++) {
 if (i%2 ==0) yield feed (i);
}
}
}

class IntGenerator_1 : Generatorint {
protected override async void generate () {
for (int i=0; i  10; i++) {
 if (i%2 !=0) yield feed (i);
}
}
}

IntGeneratorgen;
IntGenerator_1  gen_1;

void* thread_func() {
//Posix.stdout.printf(Thread running.\n);
gen = new IntGenerator();
return null;
}

void* thread_func_1() {
//Posix.stdout.printf(Thread running.\n);
gen_1 = new IntGenerator_1();
return null;
}


int main(string[] args) {

if (!Thread.supported()) {
Posix.stderr.printf(Cannot run without threads.\n);
return 1;
}

try {
unowned Threadvoid* thread = Thread.createvoid*(thread_func,
true);
thread.join();

unowned Threadvoid* thread_1 = Thread.createvoid*(thread_func_1,
true);
thread_1.join();

} catch (ThreadError e) {
return 1;
}

print(\n\nResults computed in first thread\n);

var i=0;
foreach (var item in gen) {
if (i10) Posix.stdout.printf(%i\n, item);
i++;
}

print(\n\nResults computed in the second thread\n\n);

i=0;
foreach (var item in gen_1) {
if (i10) Posix.stdout.printf(%i\n, item);
i++;
}


return 0;
}

/
___
vala-list mailing list
vala-list@gnome.org
http://mail.gnome.org/mailman/listinfo/vala-list