Looking forward to your ideas Amit.  My experience with Go (and the all-in 
recommendation to use channels for everything) is that very frequently this 
is horribly bad advice.  Channels will always be heavy weight due to the 
fact that they have to maintain multiple states and context switch between 
them.  At best, you have to deal with some extra data structures and 
processing, and at worst it destroys what could have been a nice cache for 
100x slowdowns or worse.  I built a high performance exchange with Go once 
(back when I wanted to be a bitcoin mogul), and my workflow was typically: 
1) Build clean, idiomatic Go code as recommended with channels, etc.  
2) See bad performance
3) Profile
4) Unroll to iterative algos
5) Steal underpants
6) ???
7) Profit

That being said, I think Julia has the potential for code that is as easy 
(or easier) to reason about than a "channels-centric" model, but with the 
speed of tight vectorized loops.  It would certainly be nice to have 
high-performance channels that just automatically unroll to zero-overhead 
equivalent code when appropriate. (but that's a tricky problem to get right)

On Tuesday, June 30, 2015 at 12:29:32 PM UTC-4, Amit Murthy wrote:
>
> Agree with your comments. There is enough room to speed up these 
> constructs. I have some thoughts on having channels in Base. Will post a 
> note about it on Julia-dev in a couple of days.
>
> On Tue, Jun 30, 2015 at 12:20 PM, ggggg <galen...@gmail.com <javascript:>> 
> wrote:
>
>> I'm trying to understand coroutines for single threaded concurrency. I'm 
>> surprised that produce()/consume() and RemoteRef have no mechanism for type 
>> information, and as I understand it, are type unstable. One should 
>> therefore avoid using these in inner loops I guess? Should we expect this 
>> to remain the case?
>>
>> In Go it appears to be encouraged to heavily use concurrency even for 
>> things as simple as generating a series of numbers. In julia you might say
>> a = zeros(Int,100)
>> for i=1:100 a[i]=i end
>>
>> In go you could certainly do that, but in my brief introduction it 
>> appeared to be encouraged to do create a function that pushes i onto a 
>> "channel" and then read numbers out from the channel. In julia with 
>> produce/consume instead of a channel that would look like
>> counter() = for i=1:100 produce(i) end
>> a = zeros(Int,100)
>> task = Task(counter)
>> for i=1:100 a[i]=consume(task) end
>> This seems seems to violate julia performance guidelines as I understand 
>> them, since the the compiler doesn't know what type consume(task) will 
>> return.
>>
>> So I tried to implement something more like a go channel, that has type 
>> information. I thought it would be faster
>> type GoChannel{T}
>>     v::T
>>     hasvalue::Bool
>>     c::Condition
>> end
>> It turned out to be about 2x slower than the produce()/consume() 
>> approach, and using RemoteRef (which has a more go channel like API) is 
>> about 4x slower than produce()/consume(). On my computer anyway, the 
>> produce()/consume() approach is about 7x slower than using a channel in go 
>> for the same thing.
>>
>> Gist with full code: 
>> https://gist.github.com/ggggggggg/c93a0f029620deca4f2e
>>
>> So I guess my questions are:
>> Why isn't there at least an option to encode type information in 
>> consume/produce and RemoteRef?
>> Is there anything I could do to speed up my GoChannel implementation? Did 
>> I make any mistakes in my other benchmarks?
>>
>>  I know this is one of go's defining features, so it is perhaps 
>> unsurprising that Julia isn't as fast for this yet. Is there room to speed 
>> these concurrent communication constructs up?
>>
>> Thanks.
>>
>
>

Reply via email to