Paul Davis wrote:
> 
> >Paul, I'm a wrong if I affirm that the same instruction/data cache
> >pollution is caused by plugin/component invocation in one-process
> >approach?
> 
> Yes and no.

This thread is becoming more and more instructive ;-)

I've spent some time to make a simple program to compare both approach.

I've attached it.

Results are (cost of multithreaded approach un UP, 1.3ms period time)
- AMD K6 II 333 Mhz: ~1.5% CPU for each worker
- Pentium III 800 Mhz: ~0.4% CPU for each worker

I'd like that someone measures the benefits for SMP.

If we agree on substantial correctness of test program, we may use this
numbers to make further decisions.

-- 
Abramo Bagnara                       mailto:[EMAIL PROTECTED]

Opera Unica                          Phone: +39.546.656023
Via Emilia Interna, 140
48014 Castel Bolognese (RA) - Italy

ALSA project               http://www.alsa-project.org
It sounds good!
/*
 *  Multithreaded approach cost meter
 *  Copyright (c) 2001 by Abramo Bagnara <[EMAIL PROTECTED]>
 *
 *   This library is free software; you can redistribute it and/or modify
 *   it under the terms of the GNU Library General Public License as
 *   published by the Free Software Foundation; either version 2 of
 *   the License, or (at your option) any later version.
 *
 *   This program is distributed in the hope that it will be useful,
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *   GNU Library General Public License for more details.
 *
 *   You should have received a copy of the GNU Library General Public
 *   License along with this library; if not, write to the Free Software
 *   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 *
 */

#include <limits.h>
#include <pthread.h>
#include <sched.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <assert.h>
#include <asm/msr.h>


#define BUFSIZE 64*26

struct thr {
  pthread_t thread;
  int in, out;
} threads[100];

float samples[BUFSIZE];

unsigned int _count;
volatile unsigned int *count = &_count;

void *thread(void *data)
{
        char buf[1];
        unsigned int n = (unsigned int) data;
        struct thr *t = &threads[n];
        int err;
        while (*count > 0) {
                unsigned int k;
                err = read(t->in, buf, 1);
                assert(err == 1);
                for (k = 0; k < BUFSIZE; k++)
                        samples[k]++;
                if (n == 0)
                        (*count)--;
                err = write(t->out, buf, 1);
                assert(err == 1);
        }
        return 0;
}

void proc(unsigned int n)
{
        unsigned int k;
        for (k = 0; k < BUFSIZE; k++)
                samples[k]++;
        if (n == 0)
                (*count)--;
}

void setscheduler(void)
{
        struct sched_param sched_param;

        if (sched_getparam(0, &sched_param) < 0) {
                printf("Scheduler getparam failed\n");
                return;
        }
        sched_param.sched_priority = sched_get_priority_max(SCHED_RR);
        if (!sched_setscheduler(0, SCHED_RR, &sched_param)) {
                printf("Scheduler set to Round Robin with priority %i...\n", 
sched_param.sched_priority);
                return;
        }
        printf("Scheduler set to Round Robin with priority %i failed\n", 
sched_param.sched_priority);
}


/* Usage: ctx workers periods */

int main(int argc, char **argv)
{
        unsigned long long begin, end, single, multi;
        unsigned int workers = atoi(argv[1]);
        unsigned int k;
        int err;
        char buf[1];
        unsigned int periods = atoi(argv[2]);

        _count = periods;
        for (k = 0; k < BUFSIZE; k++)
                samples[k] = 0.0;
        for (k = 0; k < workers; ++k) {
                int fds[2];
                err = pipe(fds);
                assert(err == 0);
                threads[k].in = fds[0];
                threads[k == 0 ? workers - 1 : k - 1].out = fds[1];
                err = pthread_create(&threads[k].thread, NULL, thread, (void*) k);
                assert(err == 0);
        }

        setscheduler();

        rdtscll(begin);
        while (*count > 0) {
                int n;
                for (n = 0; n < workers; ++n) {
                        proc(n);
                }
        }
        rdtscll(end);
        single = end - begin;
        printf("singlethread: %llu\n", single);

        _count = periods;
        rdtscll(begin);
        err = write(threads[workers - 1].out, buf, 1);
        assert(err == 1);
        err = pthread_join(threads[workers - 1].thread, 0);
        assert(err == 0);
        rdtscll(end);
        for (k = 0; k < workers - 1; ++k) {
                err = pthread_join(threads[k].thread, 0);
                assert(err == 0);
        }
        multi = end - begin;
        printf("multithread: %llu\n", multi);

        printf("Average cost per period: %lld\n", (multi - single) / periods);
        return 0;
}

Reply via email to