10 lines of code to play tricks with flexible scheduling

The Linux process scheduler is a general scheduler, whether it is O (n) O(n)O ( n )O (1) O (1)O ( 1 ) , or CFS, treat all processes based on a unified index. In other words, the process cannot even yield on its own.

As long as the priority of a process is determined, no matter what the scheduling algorithm is, the status of the process will never change. It would be great if the following strategy can be achieved:

  • If there are more processes in the system, it will speed up and yield.
  • If there are fewer processes in the system, preemption is accelerated.
  • When the workers came, they gave in.
  • When the manager comes, he preempts.

Consider a process A running in a specific system, it can only use up to 40% of the CPU, at this time, if there are other processes to be run, then these processes will naturally share the other 60% of the CPU, if another process A comes ? Obviously, the CPU time of the two processes A will be reduced.

Can it be guaranteed that the two processes A still use 40% of the CPU, and then other processes share the remaining 20% ​​of the CPU? It's hard!

You may say that you can configure a group, but there must be a static configuration process, which is difficult to dynamically adapt.

In other words, Linux scheduler is inelastic!

The following code shows a simple flexible scheduling:

#!/usr/local/bin/stap -g

probe kernel.function("__enqueue_entity")
{
    
    
    task = _task_of($se)
    pid = @cast(task, "struct task_struct")->pid
    if ($1 == pid) {
    
    
        _nr = $cfs_rq->nr_running
        t = $se->vruntime;
        $se->vruntime = t + 3000000*(_nr - 1)
    }
}

It means that the specified process yields according to the amount of load in the system:

  • The higher the system load, the lower the proportion of CPU time occupied by the specified process.
  • The lower the system load, the higher the proportion of CPU time occupied by the specified process.

Come and see the effect:
Insert picture description here
you can see:

  • When there is only one loop, it occupies 100% of the CPU.
  • When regenerating a loop, it almost equally divides the CPU with the first loop.
  • When more and more loops are running, the CPU share of the first loop gradually decreases.
  • This is the same root, only the first loop is flexible.

Well, the effect is ok, but not smooth enough. Try quadratic curve, or cubic curve?

$se->vruntime = t + 200*(_nr - 1)*_nr*_nr
// or
// $se->vruntime = t + 20000*(_nr - 1)*_nr

Where does 200 come from? It is necessary to adjust the parameters well.

In addition, my flexible strategy here is too single, in fact, it can be designed to be complex enough. For example, a specific strategy for a specific process, even a simple double-slope straight line segment, is better than mine, right, don’t pretend to be forced, not much Say.

Someone asked how to find the code to be modified. As long as you are familiar with the implementation principles of the Linux kernel, it is not difficult. For craftsmen, Archimedes, Luban, Pao Ding, and Huang Daopo are worthy of status. More than Euclid, Descartes.


The leather shoes in Wenzhou, Zhejiang are wet, so they won’t get fat in the rain!

Guess you like

Origin blog.csdn.net/dog250/article/details/108281228