Skip to content

High CPU usage in scheduler #2033

@tanjianfeng

Description

@tanjianfeng

With below program, we find that the scheduler shows ~380% CPU usage vs ~200% in runc.

How to test:
$ docker run -it --cpu-period=1000 --cpu-quota=8000 ...
$ gcc -o threads thread.c -lpthread
$ ./threads 1024 100000

#include <stdio.h>
#include <pthread.h>
#include <sys/time.h>
#include <time.h>
#include <string.h>
#include <unistd.h>
#include <stdlib.h>
#include <stdint.h>

struct worker_arg {
        int seq;
        int iterations;

        pthread_mutex_t count_lock;
        pthread_cond_t count_nonzero;
        unsigned count;
};


static void
park(struct worker_arg *arg)
{
        pthread_mutex_lock(&arg->count_lock);
        while (arg->count == 0)
                pthread_cond_wait(&arg->count_nonzero, &arg->count_lock);
        arg->count--;
        pthread_mutex_unlock(&arg->count_lock);
}

static void
unpark(struct worker_arg *arg)
{
        pthread_mutex_lock(&arg->count_lock);
        if (arg->count == 0)
                pthread_cond_signal(&arg->count_nonzero);
        arg->count++;
        pthread_mutex_unlock(&arg->count_lock);
}

static void *
worker(void *p)
{
        struct worker_arg *arg = (struct worker_arg *)p;

        while (arg->iterations--) {
                /* do some work */
                //printf("%d %d\n", arg->seq, arg->iterations);
                park(arg);
        }

        return NULL;
}

int
main(int argc, char **argv)
{
        int i, j, N, M;
        void *dummy;
        struct worker_arg *args;
        pthread_t *tids;

        if (argc != 3) {
                fprintf(stderr, "Usage: %s <number of threads> <iterations>\n", argv[0]);
                exit(1);
        }

        N = atoi(argv[1]);
        M = atoi(argv[2]);

        tids = malloc(sizeof(*tids) * N);
        args = malloc(sizeof(*args) * N);

        for (i = 0; i < N; i++) {
                args[i].seq = i;
                args[i].iterations = M;

                args[i].count = 0;
                pthread_mutex_init(&args[i].count_lock, NULL);
                pthread_cond_init(&args[i].count_nonzero, NULL);

                pthread_create(&tids[i], NULL, worker, &args[i]);
        }

        for (i = 0; i < M; i++) {
                for (j = 0; j < N; j++)
                        unpark(&args[j]);
        }

        for (i = 0; i < N; i++)
                pthread_join(tids[i], &dummy);
}

Metadata

Metadata

Assignees

Labels

area: performanceIssue related to performance & benchmarksauto-closedstale-issueThis issue has not been updated in 120 days.type: bugSomething isn't working

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions