为什么Linux从内核直接调用内核的一个自定义函数比在用户态调用用户态的一个类似的函数快很多?

新手上路,请多包涵

使用ubuntu16.4 内核版本4.10.1

内核sys.c中编译了一段代码:

long oper(int* result, int num1, int num2, char* op)
{
    if(op)
    {
        if(*op == '+')
            *result = num1 + num2;
        else if(*op == '-')
            *result = num1 - num2;
        else if(*op == '*')
            *result = num1 * num2;
        else if(*op == '\\')
        {
            if(num2 != 0)
                *result = num1 / num2;
            else
                printk("divided number can not be zero.\n");
        }
    }
    else
    {
        printk("operator is empty. \n");
    }
    return 0;
}
SYSCALL_DEFINE1(oper_func, int, count)
{
    printk("count is: %d\n", count);
    struct timeval tstart,tend;
    do_gettimeofday(&tstart);
    int result;
    for(i=0;i<count;i++) // +
    {
        char op_add = '+';
        oper(&result, 10, 10, &op_add);
    }
    printk("oper op_add is done. times of op_add is %d \n", i);

    for(i=0;i<count;i++) // -
    {
        char op_sub = '-';
        oper(&result, 20, 10, &op_sub);
    }
    printk("oper op_sub is done. times of op_sub is %d \n", i);

    for(i=0;i<count;i++) // *
    {
        char op_mul = '*';
        oper(&result, 10, 10, &op_mul);
    }
    printk("oper op_mul is done. times of op_mul is %d \n", i);

    for(i=0;i<count;i++) // '//'
    {
        char op_div = '+';
        oper(&result, 20, 10, &op_div);
    }
    printk("oper op_div is done. times of op_div is %d \n", i);

    do_gettimeofday(&tend);
    printk("oper_func running time is %ld usec\n", 1000000*(tend.tv_sec-tstart.tv_sec) + (tend.tv_usec-tstart.tv_usec));
    return 0;
}

系统调用代码(syscall.c):

#include <sys/syscall.h>
#include <stdio.h>
#include <unistd.h>
int main()
{
    int count = 100000*10000;
    // 系统调用号333指向了内核函数oper_func
    long ret = syscall(333,count);
    printf("result is %ld\n",ret);
    return 0;
}

用户态调用户态函数代码(usercall.cpp):

#include <stdio.h>
#include <ctime>
#include <sys/timeb.h>

using namespace std;

long operation(int* result,int num1,int num2,char* op)
{
    if(op)
    {
        if(*op == '+')
        {
            *result = num1 + num2;
        }
        else if(*op == '-')
        {
            *result = num1 - num2;
        }
        else if(*op == '*')
        {
            *result = num1*num2;
        }
        else if(*op == '\\')
        {
            if(num2!=0)
                *result = num1/num2;
            else
                printf("dived number can't be zero!\n");
        }else
            printf("unrecongized operator %c\n", *op);
    }else
    {
        printf("operation is empty.\n");
    }
    return 0;
}
int main()
{
    struct timeb starttime,endtime;
    ftime(&starttime);
    int i;
    const int count = 100000*10000;
    for(i=0;i<count;i++) // +
    {
        int result;
        char op_add = '+';
        operation(&result, 10, 10, &op_add);
    }
    for(i=0;i<count;i++) // -
    {
        int result;
        char op_sub = '-';
        operation(&result, 20, 10, &op_sub);
    }
    for(i=0;i<count;i++) // *
    {
        int result;
        char op_mul = '*';
        operation(&result, 10, 10, &op_mul);
    }
    for(i=0;i<count;i++) // '//'
    {
        int result;
        char op_div = '+';
        operation(&result, 20, 10, &op_div);
    }
    ftime(&endtime);
    printf("usrcall count: %d time use: %ld usec\n", count, 1000*1000*(endtime.time - starttime.time) + (endtime.millitm - starttime.millitm));
    return 0;
}

运行结果:

xkl@xkl:~/Desktop/代码/实验2$ sudo ./usercall
usrcall count: 1000000000 time use: 13921 msec
xkl@xkl:~/Desktop/代码/实验2$ sudo ./syscall
result is 0
xkl@xkl:~/Desktop/代码/实验2$ dmesg
[   83.813329] count is: 1000000000
[   83.813330] xuchufeng_oper op_add is done. times of op_add is 1000000000 
[   83.813331] xuchufeng_oper op_sub is done. times of op_sub is 1000000000 
[   83.813331] xuchufeng_oper op_mul is done. times of op_mul is 1000000000 
[   83.813331] xuchufeng_oper op_div is done. times of op_div is 1000000000 
[   83.813332] xuchufeng_oper_func running time is 2 usec

请问,为什么内核的速度会快这么多?

阅读 2.1k
撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题