in reply to Why Coro?

To answer your second question.

The main advantage Coro, has, is lighter weight execution contexts.

For your stated requirements, 3000 to 12000 threads, unless you are running on some massively parallel hardware, your problem must be IO-bound rather than CPU-bound. Even on one of AMD 48-core motherboards, running 3000/12000 CPU-bound threads would involve so much context switching that you would waste a huge portion of your overall clock cycles.

For IO-bound applications where you have (say), large numbers of concurrent tcp conversations that spend most of their time waiting for responses, Coro is probably your better bet.

Though, if you have multiple cores, your application will be limited to using only one core at a time, which may prove limiting.

Perhaps the best solution would be to run a Coro scheduler instance inside each of multiple threads--one per core--and split your conversations between them. This still has the limitation that only a single conversation within a given Coro instance will be able to be run concurrently; but will allow concurrency by conversations in different groups.

It is also unclear whether the underlying libcoro library is thread-safe. If it is, ithreads will have no problem running those multiple instances, but it is a big if.

I'd love to see a high-level description of the task that requires 3000 to 12000 threads?


Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
"Science is about questioning the status quo. Questioning authority".
In the absence of evidence, opinion is indistinguishable from prejudice.
RIP an inspiration; A true Folk's Guy

Replies are listed 'Best First'.
Re^2: Why Coro?
by Anonymous Monk on Jul 28, 2010 at 05:08 UTC

    Many Thanks! I'll try my best to mention the task clear as sooner as I can ;)

    There are 3000 devices(will add to 12000 in near future) in a big area such as NY(just presume).;) Every one minute, device will store a 8 decimal number(like 00004000) in its register. Always, it just store the newest value in register, that means the old value will be overwritten on the next one minute.

    So I intend to write a multi-methods program running in server side to get data. But after reading your post, now I think I can just run the program on server machines and store to one database. Is it a better idea?

    Besides, The ways which devices connect to server might be diverse like TCP, serial, modem etc.

      Every one minute, device will store a 8 decimal number(like 00004000) in its register.

      Can you clarify the definitions of "device" (type?), and "register" in this context?

      Specifically, will there be custom software running on each of these devices that receives the TCP requests, reads the "register" and replies with the value read?

      Or are the registers on the devices accessible directly via a TCP request? (Perhpas via firmware?)

      If the former is the case, then you could more simply have that custom software read the register and send it to the DB directly. The read and send cycle could be synchronised to the local hardware, and the DB & TCP take care of queuing the data at the DB end. Very simple and reliable.

      If the latter, the problem of whether Coro alone is suitable comes down to whether a single thread can dispatch & retrieve, with context switches, to 12000 machines in 60 seconds. 12000/60 = 200. Assuming permanent connections, that's 200 writes, 200 reads and 400 context switches per second. On a Gigabit LAN maybe you'd be okay, but I think you'd be pushing your luck across a WAN or the internet. With 8 or 12 cores, it would probably be okay. Though I'd want more information about latencies to convince myself of that.

      Multiple Coro instances (processes), whether running on the one or more multi-core machines, sounds like a possible solution. Though you still have the problem that if all the devices allocated to a particular instance decide to respond at the same instance, they will all be serialised through one core/machine, whilst all the others (potentially) stand idle. Ensuring that you poll every device one per minute reliably would require extensive testing.

      The upside is that you should be able to determine the maximum number of devices a single instance can reliably support during testing, and then split your devices in to suitably sized groups. As the number of machines ramps up, you just start more processes. The downside is that you have to carry the overheads of running many more instances than are required for the average case in order to ensure for the occasional confluence spike.

      If you have the opportunity to have the devices post their data to the DB directly rather than polling, you should definitely opt for that. But reading between the lines I suspect that you are talking about SNMP devices?

      If these are SNMP requests, then you should also look closely at the non-blocking request protocols in Net::SNMP. It may be all you need.


      Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
      "Science is about questioning the status quo. Questioning authority".
      In the absence of evidence, opinion is indistinguishable from prejudice.
        I second the Net::SNMP note. I've used the non-blocking stuff in production on blocks of 10000 hosts from a single process and usually been able to get all of them in a minute.
        For the multiple Coro instances situation you might look at Coro-MP which is a Coro wrapper over AnyEvent-MP which lets you co-ordinate multiple AnyEvent loops / Coro instances running in separate processes on one or multiple hosts
      s/sever/several/