Details of wake-up neutron processes in the CFS scheduler-experiment and theory

Source: Internet
Author: User

Before I submitted and installed the child-runs-first patch, I did an experiment to verify the results of my previous theoretical analysis, in my opinion, sub-processes may be more likely to seize the parent process no matter how they seize the parent process. Of course, the premise is yes. For details, see the experiment below. Null theory is useless. Theoretically, the CFS scheduler implements strict normalization, but in fact it is not. The practical results are always more realistic than the theory, the absence of normalization does not affect the process of selecting the minimum vruntime for the CFS scheduler. This is very simple. Each process executes the dynamic time slice based on its own weight and the current system scheduling cycle, at the same time, you can push your own virtual time at different rates. The Scheduler only needs to ensure that each process can push forward the same virtual time after running the different time slices assigned to them according to their weights, what is his normalization? In this way, the CFS scheduler runs well.

Environment: single CPU, Hz = 250, linux-2.6.28 original kernel (not hitting my child_runs_first patch)

Kernel configuration and experimental prerequisites: sysctl_sched_child_runs_first = 0, sysctl_sched_features = (Open akeup_preempt only), expires = 0, sysctl_sched_latency_ns = 20000000.

Objective: To test the behavior of the CFS scheduler when the child process is awakened without the sysctl_sched_child_runs_first Policy

Test procedure:

------- Stub --------

/* Simulate the CPU process and increase the nr_running of cfs_rq To a certain number */

Int main (INT argc, char * argv [])

{

Nice (atoi (argv [1]);

Int A = 1, B = 0;

While (A ++ | 1)

{

B + =;

}

}

------- Child_run_delay --------

/* The parent process will be delayed for a moment before fork, avoiding the blessing of the parent process min_vruntime given by shell in the fork parent process */

# Include

# Include

# Include

Int main (INT argc, char * argv [])

{

Int v = atoi (argv [1]);

Nice (v );

Unsigned long I = 1000000;

While (I --> 0)

{

V ++;

}

If (Fork () = 0)

{

Printf ("sub/N ");

Exit (0 );

}

Printf ("Main, % d/N", V );

}

------- Child_run_nodelay --------

/* Immediately Fork sub-processes, with a very small value for the parent process vruntime */

# Include

# Include

# Include

Int main (INT argc, char * argv [])

{

Int v = atoi (argv [1]);

Nice (v );

If (Fork () = 0)

{

Printf ("sub/N ");

Exit (0 );

}

Printf ("Main/N ");

}

Test process: Nine stub processes are created consecutively. Nice values are dispersed and child_run_delay and child_run_nodelay are run with different nice values.

Result:

Test result when I = 1000 in the test code

 

Child_run_delay

Child_run_nodelay

Nice 15

96% preempt

95% preempt

Nice 10

96% preempt

94% preempt

Nice-10

70% preempt

12% preempt

Nice-17

64% preempt

10% preempt

Nice-20

11% preempt

4% preempt

Test result when I = 10000000 in the test code

 

Child_run_delay

Child_run_nodelay

Nice 15

36% preempt

96% preempt

Nice 10

33% preempt

96% preempt

Nice-10

24% preempt

10% preempt

Nice-17

15% preempt

9% preempt

Nice-20

9% preempt

6% preempt

Result Analysis:

The creation of child_run_delay process and child_run_nodelay process is also the result of shell execution fork. At that time, these processes will be assigned to the min_vruntime of cfs_rq. In any case, this vruntime is the smallest vruntime of all processes, including the ongoing curr (because min_vruntime is updated in real time in update_curr), The min_vruntime of cfs_rq increases monotonically only when the current process is the last process to be dropped, the min_vruntime of cfs_rq will be equal to the vruntime of curr. That is to say, min_vruntime of cfs_rq will always be the smallest vruntime, which is better than that before 2.6.28, the vruntime distance between processes will not be extended, resulting in unfair access to processes with large vruntime values. Since the vruntime of the child_run_delay process and the child_run_nodelay process is the smallest, if their nice values are small, the virtual clock will slow down. When fork is reached, the vruntime may be the smallest, therefore, based on the Code and Kernel configuration, the chances of preemption will decrease. What is becoming smaller? Who is better than who? In fact, when the main program was just executed and fork was compared, there was another comparison, that is, the comparison between the delay program and the nodelay program. For nodely, the chances of preemption is lower, because when the parent process takes advantage of its minimum vruntime, it almost immediately fork the child process. At this time, the child process is assigned the minimum min_vruntime, at this time, the vruntime is very likely because the parent process has not yet promoted a few vruntime steps. If the nice value of the parent process is small, the process will be slower and the chances of not preemption will be greater, however, if the nice value of the parent process is very large, the virtual clock, that is, the vruntime, will be promoted very quickly, and the execution will not be the smallest, when fork is reached, preemption is a very high probability.

Sched_latency_ns is relatively small. When vruntime is very active, even if the child_run_delay test process of the Nice value of-20 is executed, the process may be preemptible and the probability is high, this seems to be the opposite of the above analysis. Why, because after a very large meeting, CPU commands and sleep are executed, the vruntime of the process is not necessarily the last running process in a System Scheduling cycle (sysctl_sched_latency_ns) even if the weight is higher, not to mention the process's uncertain sleep wake-up and quit, strict Virtual Clock normalization has been disrupted, as long as it is not the last running process, that is, as long as it is said that this process is not the Fallen One, the vruntime of the process must be greater than the min_vruntime of cfs_rq. Therefore, when the Fork sub-process is running, because the min_vruntime of cfs_rq gives the new process, the vruntime of the new process is smaller than the vrunti of the current (parent process with high weights ). If the preemption granularity is small, the child process will seize the parent process. To simplify the process, we set the preemption granularity to 0, so the preemption occurs. However, if the parent process with a high weight is the last running process, its virtual clock is very slow, so it is likely that its vruntime will always be the min_vruntime of cfs_rq, if yes, the preemption will not occur. However, even if the vruntime of the process is equal to the vruntime of cfs_rq in this case, the chances of the process being dropped to the last one are very small, after all, it is possible that every process is dropped to the last one. Therefore, in any case, the probability of preemption is higher than that of non-preemption, if the number of active processes is reduced, the probability of no preemption increases, but the statistical sense is still higher than the probability of preemption. The longer the time before fork executes the CPU command, the more obvious the effect is.

Concealed truth: If the I value in child_run_delay is reduced, the result is that the lower the nice value, the less likely the process will be preemptible. This is actually introduced by shell when executing our test program. For the reason, see the above analysis. The I value is small enough, and the I -- cycle time does not reach the dynamic time slice of the parent process, therefore, results that are easy to mislead users are displayed.

Truth: do not think that a process with a large weight will be run at the end. Do not think that the vruntime of a process with a large weight must be the min_vruntime of cfs_rq. This is not the case, based on the ideal situation, it is not certain who will run the task in a scheduling cycle. It depends on the order of their queues and the existing situation of the red and black trees when they are in the queue. When the parent process is created by shell without being given a small vruntime advantage, that is, if the fork runs for a long enough time without sleep, fork has a higher chance of sub-process preempting the parent process, which is not necessarily related to the priority of the parent process, it can only be said that process preemption with Low weights under the same conditions is definitely more likely, but it will never exceed the probability of non-preemption, because so many processes will not be preemptible as long as the parent process is not the last running, and the last running chance of each process is almost equal.

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.