7

I am trying to understand how CPU is distributed among different processes with different no of threads.I have two programs Program1 and Program2.

Program1 has 5 threads whereas Program2 has ONLY main thread.

SCENARIO -1 :

terminal-1 :  ./Program1 
terminal-2 :  ./Program2 

When I run Program1 in one terminal and Program2 in another terminal , the CPU allocation is done 50% for Program1 and 50% for Program2. Each thread of Program1 is getting 10% (cumulatively 50% for Program1)

This shows, no matter the no of threads a process have, every process will get equal share of CPU. This shows CPU allocation is done at Process level.

pstree shows

├─bash───P1───5*[{P1}]
├─bash───P2───{P2}

SCENARIO -2 :

terminal-1 : ./Program1 &  ./Program2

When I run both Program1 and Program2 in SAME terminal , the CPU allocation is done equal for Program1 and all threads of Program2. It means each thread of Program1 is getting almost 17% (cumulatively Program1 is getting 83%) and Program2 is also getting 17%. This shows CPU allocation is done at Thread level.

pstree shows

 ├─bash─┬─P1───5*[{P1}]
 │      └─P2

I am using Ubuntu 12.04.4 LTS, kernel - config-3.11.0-15-generic. I have also used Ubuntu 14.04.4 , kernel-3.16.x and got similar results.

Can anyone explain how CPU scheduler of LINUX KERNEL distinguishing SCENARIO-1 and SCENARIO-2?

I think the CPU scheduler is distinguishing both SCENARIO in somewhere before allocating CPU. To understand how CPU scheduler is distinguishing SCENARIO-1 and SCENARIO-2 ,I have downloaded Linux kernel source code.
However, I haven't found in source code where it is distinguishing SCENARIO-1 and SCENARIO-2. It will be great if anyone point me the source code or function where the CPU scheduler is distinguishing SCENARIO-1 and SCENARIO-2.

Thanks in advance.

NOTE : Although Ubuntu is based on Debian, surprisingly, in Debian 8 (kernel-3.16.0-4-686-pae) in both SCENARIO's CPU allocation is done at Thread level means each thread of Program1 is getting almost 17% (cumulatively Program1 is getting 83%) and Program2 is also getting 17%.

Here is the code : Program1(with 5 threads)

#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>

// Let us create a global variable to change it in threads
int g = 0;

// The function to be executed by all threads
void *myThreadFun(void *vargp)
{

    // Store the value argument passed to this thread
    int myid = (int)vargp;

    // Let us create a static variable to observe its changes
    static int s = 0;

    // Change static and global variables
    ++s; ++g;

    // Print the argument, static and global variables
    printf("Thread ID: %d, Static: %d, Global: %d\n", myid, ++s, ++g);

while(1); // Representing CPU Bound Work

}

int main()
{
    int i;
    pthread_t tid[5];

    // Let us create three threads
    for (i = 0; i < 5; i++)
        pthread_create(&tid[i], NULL, myThreadFun, (void *)i);

    for (i = 0; i < 5; i++)
     pthread_join(tid[i],NULL);

    return 0;
}

Program2 ( with only main thread)

#include <stdio.h>
#include <stdlib.h>

int main()
{
 while(1);// Representing CPU Bound Work
}

To disable all optimization by gcc, I have used O0 option while compiling the both programs.

gcc -O0 program1.c -o p1 -lpthread
gcc -O0 program2.c -o p2 

UPDATE: As per explanation of ninjalj , in Scenario-1, CPU allocation is done at control groups level and as I am using two different terminal(means two different session), thus 2 different control groups and each control groups is getting 50% CPU allocation. This is due to reason, autogroup is enabled by default.

As Program2 has ONLY one thread and Program1 has more threads, I want to run both the program in separate terminal(different session) and get more CPU allocation for Program1 ( as in Scenario-2, Program1 is getting 83% CPU allocation compared to 17% of Program2). Is it possible in any way,that CPU allocation of Scenario1 will be same as Scenario-2 in Ubuntu?

Also it is surprising to me although Ubuntu is based on Debian, still Debian and Ubuntu is behaving differently. In case of Debian, Program1 is getting more CPU in both Scenario.

bholanath
  • 1,699
  • 1
  • 22
  • 40
  • 3
    "*This shows, no matter the no of threads a process have, every process will get equal share of CPU. This shows CPU allocation is done at Process level.*" Nonsense. It shows no such thing. – David Schwartz Feb 24 '16 at 23:43
  • 1
    I'm quite confident the scheduling algorithms are documented somewhere. At least the source code is available. – too honest for this site Feb 24 '16 at 23:50
  • 1
    @DavidSchwartz, the experimental results show that in Scenario-1 , each process are getting equal share of CPU. I don't understand why you say "It shows no such thing" ? Can you elaborate ? – bholanath Feb 24 '16 at 23:51
  • @Olaf, I have downloaded the source code from kernel.org. However, not able to find the function where kernel/CPU scheduler decides the CPU allocation and distinguishing above two Scenario . – bholanath Feb 24 '16 at 23:53
  • @bholanath You're assuming that both programs keep all their threads ready to run all the time. What is that assumption based on? – David Schwartz Feb 24 '16 at 23:57
  • @DavidSchwartz , both the program is CPU intensive processes and no threads are releasing CPU voluntarily. – bholanath Feb 25 '16 at 00:05
  • @bholanath Can you post a link to the programs so we can confirm that? – David Schwartz Feb 25 '16 at 00:17
  • 1
    Possible duplicate of [Understanding renice](http://stackoverflow.com/questions/22090126/understanding-renice) – ninjalj Feb 25 '16 at 00:27
  • 1
    @SergeyA: terminal emulators can have multiple tabs, just as web browsers. In particular, each tab will have a different session, which affects scheduling when autogroups are enabled (each session is put into a different control group for scheduling purposes). – ninjalj Feb 25 '16 at 00:30
  • @SergeyA tab means gnome terminal. As different tab is causing more confusion, I have replace it by terminal. – bholanath Feb 25 '16 at 00:30
  • 2
    Experiment 1 doesn't "_[show] CPU allocation is done at Process level_". In that case, it is actually done at control group level, and inside each control group, it's then done at thread level. – ninjalj Feb 25 '16 at 00:35
  • @njnjalj thanks! Now it makes sense. – SergeyA Feb 25 '16 at 00:35
  • @ninjalj, post an answer, so that i can upvote! – SergeyA Feb 25 '16 at 00:38
  • @SergeyA: it's basically a dupe (the other question talks about renice in the title, but both questions are about CPU allocation in 1 vs 2 sessions). I see no reason to repeat myself. – ninjalj Feb 25 '16 at 00:48
  • @ninjalj thanks for good explanation. As per explanation in link pointed by you , Possible duplicate of Understanding renice , in Experiment1 I have 2 control groups (one per session) competing for CPU, and inside each control group processes compete for CPU. Thus Program1 is getting 50% and Program2 is getting 50%. Then each thread is getting equal share(10%) from 50% share of Program1. – bholanath Feb 25 '16 at 00:51
  • @ninjalj, as per the link (Possible duplicate of Understanding renice), you said by default autogroups is enabled. According to you, in experiment 1 at the top level I have 2 control groups (one per session) competing for CPU, and inside each control group processes compete for CPU. That's why 50% for Program2, 10% for each thread of Program1. I have checked and found cat /proc/$$/autogroup is /autogroup-127 nice 0 (nexttime /autogroup-131 nice 0). However, in Debian 8 (kernel 3.16.0-4-686-pae) output of cat /proc/$$/autogroup is /autogroup-64 nice 0 ( nextime also /autogroup-64 nice 0). – bholanath Feb 25 '16 at 01:06
  • Although Ubuntu is based on Debian and in both Ubuntu and Debian autogroup is enabled , still Ubuntu and Debian are behaving differently. I mean in Debian for experiment1, I am getting the same output as experiment2,means Program1 is getting more CPU(83%), Program2-17%. What you say about it ? After executing echo 19 > /proc/$$/autogroup and then running both Program1 and Program2 in two different terminal with nice 19, I am getting 50% for Program1, 50% for Program2. – bholanath Feb 25 '16 at 01:12

1 Answers1

5

The linux kernel does not distinguish processes vs. threads in scheduling.

Threads are processes that just happen to share most of their memory. Beyond that, they are treated equally by the scheduler.

You can have 50 processes and 30 threads. That's 80 "things" and the kernel will schedule them without regard to whether they are processes or threads

Craig Estey
  • 30,627
  • 4
  • 24
  • 48
  • thanks for commenting. The experimental results show that when a process have more threads it got more CPU (Scenario-2) , whereas in Scenario-1 , CPU allocation is not dependent on no of threads a process has, means every process will get equal share of CPU and that CPU share will be further equally divided among threads of that process. – bholanath Feb 24 '16 at 23:56
  • Why don't you post your measurement code and test rig. If you look at `/proc//...` for this, a multithread process will report the cumulative for its threads. To see the per-thread, look at `/proc//task//...`. – Craig Estey Feb 25 '16 at 00:04
  • I have checked using top -H and the results shows about all threads. – bholanath Feb 25 '16 at 00:07
  • both the program is CPU intensive processes and no threads are releasing CPU voluntarily. – bholanath Feb 25 '16 at 00:08
  • What do you mean by [running in a] "tab"? I don't believe I've ever heard of this term with regard to process scheduling before. – Craig Estey Feb 25 '16 at 00:22
  • by tab I mean to say terminal. two different tab means in two different terminal. pstree shows the difference. – bholanath Feb 25 '16 at 00:25