Puzzled by the cpushare setting on Docker.

I wrote a test program ‘cputest.py’ in python like this:

import time
 while True:
    for _ in range(10120*40):

, which costs 80% cpu when running in a container (without interference of other runnng containers).

  • How to Increase number of cpus on Docker
  • Building CPU usage graph in Grafana for Docker container
  • My 'docker run' command uses 2 cpu cores by default. How to increase it?
  • Docker Compose shared CPUs
  • Application takes different amount of memory on different systems
  • How can I show only the allocated resources in Docker container?
  • Then I ran this program in two containers by the following two commands:

    docker run -d -c 256 --cpuset=1 IMAGENAME python /cputest.py
    docker run -d -c 1024 --cpuset=1 IMAGENAME python /cputest.py

    and used ‘top’ to view their cpu costs. It turned out that they relatively cost 30% and 67% cpu. I’m pretty puzzled by this result. Would anyone kindly explain it for me? Many thanks!

  • Citrus-Framework: How to wait for container to be healthy?
  • Start a service in docker container failed,with error: Failed to get D-Bus connection: No connection to service manager
  • How to change Docker daemon's arguments in OSX
  • Can I run the service on 443 port in docker UCP ??
  • ECS updating service with same tasks but different docker image
  • How to solve classcastexception of same class for ehcache
  • One Solution collect form web for “Puzzled by the cpushare setting on Docker.”

    I sat down last night and tried to figure this out on my own, but ended up not being able to explain the 70 / 30 split either. So, I sent an email to some other devs and got this response, which I think makes sense:

    I think you are slightly misunderstanding how task scheduling works – which is why the maths doesn’t work. I’ll try and dig out a good article but at a basic level the kernel assigns slices of time to each task that needs to execute and allocates slices to tasks with the given priorities.

    So with those priorities and the tight looped code (no sleep) the kernel assigns 4/5 of the slots to a and 1/5 to b. Hence the 80/20 split.

    However when you add in sleep it gets more complex. Sleep basically tells the kernel to yield the current task and then execution will return to that task after the sleep time has elapsed. It could be longer than the time given – especially if there are higher priority tasks running. When nothing else is running the kernel then just sits idle for the sleep time.

    But when you have two tasks the sleeps allow the two tasks to interweave. So when one sleeps the other can execute. This likely leads to a complex execution which you can’t model with simple maths. Feel free to prove me wrong there!

    I think another reason for the 70/30 split is the way you are doing “80% load”. The numbers you have chosen for the loop and the sleep just happen to work on your PC with a single task executing. You could try moving the loop to be based on elapsed time – so loop for 0.8 then sleep for 0.2. That might give you something closer to 80/20 but I don’t know.

    So in essence, your time.sleep() call is skewing your expected numbers, removing the time.sleep() causes the CPU load to be far closer to what you’d expect.

    Docker will be the best open platform for developers and sysadmins to build, ship, and run distributed applications.