That's a bummer; it sounds like Fibers will never really be useful on the 
MacRuby platform then?  :(

Out of curiosity, is there a limiting factor in the runtime that prevents the 
use of, e.g., makecontext/setcontext or related call?  

Logan Bowers

On Aug 11, 2010, at 1:56 PM, Laurent Sansonetti wrote:

> Hi Scott,
> 
> Because of the way MacRuby is implemented, fibers would need to unwind the 
> stack most of the time you switch continuations, which has poor runtime 
> performance. We will eventually implement continuations which can serve to 
> implement fibers at some point (which is what MRI does I believe), but I 
> wouldn't recommend to use them for anything significant because of the 
> performance impact.
> 
> Another issue is that unwinding the stack would likely mess with Objective-C 
> exception handlers, unless they are implemented using exceptions, which would 
> impact performance even worser (because we use dwarf exceptions).
> 
> I personally believe the GCD model is much more appealing to achieve 
> multitasking, especially now that we enter the multicore age.
> 
> Laurent
> 
> On Aug 11, 2010, at 6:06 AM, Scott Thompson wrote:
> 
>> 
>> On Aug 11, 2010, at 7:23 AM, Louis-Philippe wrote:
>> 
>>> Hi Scott,
>>> 
>>> If you haven't done so already, you might want to have a look at:
>>> http://www.macruby.org/documentation/gcd.html
>>> 
>>> it speaks of MacRuby integrating Apple's latest multi-threading strategy: 
>>> Grand Central Dispatch.
>> 
>> Grand Central Dispatch is a fine technology, and goes a long way toward 
>> making concurrency much easier to implement.  But concurrent  execution is 
>> only one form of multitasking and GCD is not a general solution to all 
>> multitasking problems. In this particular case we are talking about 
>> cooperatively scheduled coroutines which is multitasking, but not 
>> necessarily concurrency.
>> 
>> In Grand Central Dispatch, work is broken up in to a number of small units 
>> and those units are dispatched to queues.  Eventually a preemptive thread 
>> will come along and pick up that work, run it (possibly in parallel with 
>> other bits of work). When a thread runs some of the work, however, it runs 
>> that work all the way through. 
>> 
>> Contrast that with a Fiber.  Like a block, a fiber represents a unit of work 
>> you need to do, but it's work you can turn your attention to... spend some 
>> time on, and then put down again at predefined spots.  Later, when you are 
>> ready, you can pick up that work and continue at the same spot.  This is 
>> multitasking, but not concurrency.  Consider a simple example:
>> 
>> my_fiber = Fiber.new do
>>      number = 0
>>      loop do
>>              Fiber.yield number
>>              number = number + 1
>>      end
>> end
>> 
>> >> my_fiber.resume
>> => 0
>> 
>> >> my_fiber.resume
>> => 1
>> 
>> This is a coroutine. It has it's own execution context which is started with 
>> the first resume, runs up until the yield, and then suspends execution.  
>> This is a simple example, but the coroutine could be calling other 
>> subroutines, or other complex tasks, with the yield suspending execution at 
>> any point along the way. At some point in the future, resume may be called 
>> again and execution continues where it left off up until the next time yield 
>> is called.
>> 
>> This type of multitasking would be hard to implement using GCD because GCD 
>> focuses on concurrency. Since each GCD block runs to completion, the 
>> solution would involve breaking up the Ruby code using the yield statements 
>> as boundaries and then dispatching those blocks to a queue. But that 
>> solution would quickly become untenable if you consider that the yield 
>> statements might come... say... in the middle of a case:while statement, or 
>> in the middle of a complex subroutine chain.
>> 
>> Another solution you might come up with is to submit the whole Fiber's block 
>> as a single GCD block and implement the yield as acquiring some 
>> multiprocessing lock (a semaphore or a condition lock for example).  If you 
>> do that, then you've got the added overhead of a concurrency lock for each 
>> yield and you've submitted a GCD block to a queue that contains an infinite 
>> loop.  That block is going to sit at the end of the queue, consuming one of 
>> the threads from the thread pool "forever".  If you get a bunch of these 
>> running at once... GCD is not going to be happy with your train cars sitting 
>> on his tracks.
>> 
>> Please don't get me wrong.  I __LOVE___ all the work that has gone into 
>> integrating GCD into MacRuby.  But I don't see how GCD is going to help 
>> someone implement the cooperative multitasking of Fibers, a Ruby 1.9 
>> language feature.
>> 
>> Scott
>> _______________________________________________
>> MacRuby-devel mailing list
>> MacRuby-devel@lists.macosforge.org
>> http://lists.macosforge.org/mailman/listinfo.cgi/macruby-devel
> 
> _______________________________________________
> MacRuby-devel mailing list
> MacRuby-devel@lists.macosforge.org
> http://lists.macosforge.org/mailman/listinfo.cgi/macruby-devel

_______________________________________________
MacRuby-devel mailing list
MacRuby-devel@lists.macosforge.org
http://lists.macosforge.org/mailman/listinfo.cgi/macruby-devel

Reply via email to