Feature request: ability to use libeio with multiple event loops

Hongli Lai hongli at phusion.nl
Wed Dec 21 21:38:01 CET 2011


On Wed, Dec 21, 2011 at 1:46 AM, Marc Lehmann <schmorp at schmorp.de> wrote:
> Well, threads were originally invented because single cpus only had a single
> set of registers, and swapping these can be costly (especially with vm
> state).

I agree with your assertion that single CPUs had a single set of
registers and that swapping registers can be costly. But what does
this have to do with the invention of threads? Are you saying that by
using threads, CPUs do not have to swap registers?

Are you talking about hardware simultaneous multithreading
(http://en.wikipedia.org/wiki/Simultaneous_multithreading), e.g.
HyperThreading?


> With multiple cpus, this is no concern, because each cpu has it's own
> set of registers, so there is no benefit in keeping register values
> in-sync. In fact, having to keep state in sync is now a major problem, as
> ipmi's are quite costly.
>
> Also, sharing memory is a speed problem, as hardware doesn't share
> memory in the way threads normally need it (every cpu has it's own cache
> for example), and bouncing cache lines between cpus is a very common
> phenomenon. The more cpus, the more costly this gets.

Agreed.


> In addition, your cpu has a mmu, that allows programs to have different
> state without extra pointer indirection. With threads, you cannot use the MMU
> for this task anymore, which replaces a whole block of optimised silicon in
> your cpu by a software mmu implementation, because everything that cannot be
> shared requires extra indirection _somewhere_.

Let me get this right before continuing the discussion. Are you saying
that this program (in pseudo code):

---------------------
static some_type global_variable_1;
static some_type global_variable_2;

function do_work() {
    while (some_condition()) {
       // do some work and update global_variable_1 and global_variable_2
    }
}

function main() {
    for (i = 0; i < N; i++) {
        if (fork() == 0) {
            do_work();
        }
    }
    wait_until_all_child_processes_are_done();
}
---------------------

is faster than this program?

---------------------
struct ThreadData {
    some_type variable_1;
    some_type variable_2;
};

function thread_callback(ThreadData *data) {
    while (some_condition()) {
        // do some work and update data->variable_1 and data->variable_2
    }
}

function main() {
    for (i = 0; i < N; i++) {
        thread_data = malloc(sizeof(ThreadData));
        spawn_thread(thread_callback, thread_data);
    }
    wait_for_all_threads();
}
---------------------

-- 
Phusion | Ruby & Rails deployment, scaling and tuning solutions

Web: http://www.phusion.nl/
E-mail: info at phusion.nl
Chamber of commerce no: 08173483 (The Netherlands)



More information about the libev mailing list