通常,在ucLinux上,ioctl比写入/sys文件系统快吗?

通常,在ucLinux上,ioctl比写入/sys文件系统快吗?,linux,sysfs,Linux,Sysfs,我有一个正在使用的嵌入式系统,它目前使用sysfs来控制某些功能 但是,如果可能的话,我们希望加快功能 我发现这个子系统也支持和ioctl接口,但是在重写代码之前,我决定搜索一下,看看哪个接口(在ucLinux上)通常更快:sysfs还是ioctl 是否有人对这两种实现都非常了解,可以让我大致了解每种实现的开销差异?我在寻找一般信息,比如“ioctl更快,因为您已经从函数调用中删除了文件层”。或者“它们大致相同,因为sysfs有一个非常简单的接口” 2013年10月24日更新: 我目前正在做的具

我有一个正在使用的嵌入式系统,它目前使用sysfs来控制某些功能

但是,如果可能的话,我们希望加快功能

我发现这个子系统也支持和ioctl接口,但是在重写代码之前,我决定搜索一下,看看哪个接口(在ucLinux上)通常更快:sysfs还是ioctl

是否有人对这两种实现都非常了解,可以让我大致了解每种实现的开销差异?我在寻找一般信息,比如“ioctl更快,因为您已经从函数调用中删除了文件层”。或者“它们大致相同,因为sysfs有一个非常简单的接口”

2013年10月24日更新:

我目前正在做的具体案例如下:

int fd = open("/sys/power/state",O_WRONLY);
write( fd, "standby", 7 );
close( fd );
在kernel/power/main.c中,处理此写入的代码如下所示:

static ssize_t state_store(struct kobject *kobj, struct kobj_attribute *attr,
               const char *buf, size_t n)
{
#ifdef CONFIG_SUSPEND
    suspend_state_t state = PM_SUSPEND_STANDBY;
    const char * const *s;
#endif
    char *p;
    int len;
    int error = -EINVAL;

    p = memchr(buf, '\n', n);
    len = p ? p - buf : n;

    /* First, check if we are requested to hibernate */
    if (len == 7 && !strncmp(buf, "standby", len)) {
        error = enter_standby();
  goto Exit;
    ((( snip )))
可以通过移动到自定义ioctl()来加快这一速度,其中处理ioctl调用的代码如下所示:

case SNAPSHOT_STANDBY:
    if (!data->frozen) {
        error = -EPERM;
        break;
    }
    error = enter_standby();
    break;

(因此ioctl()调用与sysfs函数相同的低级函数)。

如果sysfs指的是
sysfs()
库调用,请注意
man2sysfs
中的这一点:

注释

此System-V派生的系统调用已过时;不要使用它。在带有/proc的系统上,可以通过 /进程/文件系统;改用该接口

我记不起注意到有
ioctl()
和sysfs接口的东西,但它们可能存在。无论如何,我都会使用proc或sys句柄,因为这往往不那么神秘,也更灵活

如果说sysfs是指访问
/sys
中的文件,那么这是首选方法

我在寻找一般信息,比如“ioctl更快,因为您已经从函数调用中删除了文件层”

访问procfs或sysfs文件不需要I/O瓶颈,因为它们不是真正的文件——它们是内核接口。因此,通过“文件层”访问这些内容不会影响性能。我认为,在linux系统编程中,这是一种常见的误解。程序员可能会对不好的系统调用、系统调用感到不安,并且偏执地认为打开文件会以某种方式变慢。当然,ABI中的文件I/O只是系统调用。使普通(磁盘)文件读取变慢的不是对打开、读取、写入的调用,而是硬件瓶颈


我总是使用基于低级描述符的函数(
open()
read()
)而不是高级流,因为在某种程度上,一些经验让我相信它们在这方面更可靠(阅读
/proc
)。我不能肯定这是否是真的

所以,这个问题很有趣,我构建了两个模块,一个用于ioctl,一个用于sysfs,ioctl只实现来自用户的4字节拷贝,而sysfs的写接口中没有任何内容

然后进行两次用户空间测试,最多100万次迭代,结果如下:

time ./sysfs /sys/kernel/kobject_example/bar 

real    0m0.427s
user    0m0.056s
sys     0m0.368s

time ./ioctl /run/temp 

real    0m0.236s
user    0m0.060s
sys     0m0.172s
编辑

我同意@goldilocks的回答,硬件是真正的瓶颈,在一个编写良好的驱动程序的Linux环境中,选择ioctl或sysfs并不会产生很大的影响,但是如果您在硬件中使用uClinux,即使是很少的cpu周期也可能会产生影响


我所做的测试是针对Linux而不是uClinux的,它从来都不想成为评测这两个接口的绝对参考,我的观点是,你可以写一本书,介绍这两个接口的速度,但只有测试才能让你知道,我花了几分钟来设置它。

哇,我没想到会这样。快了将近50%?这太棒了,Alex,tgz和使用的资源。dl链接将在几天内有效。这似乎是一个有点欺骗性的例子——我的意思不是故意欺骗性的,但仍然是欺骗性的。sysfs示例返回以前创建和存储的真实(尽管是空的)数据,而ioctl示例只是一个回音。另一个问题是,你所做的基准测试可能类似于基准测试某人进入汽车并启动点火开关进行比赛所需的时间——这是真的,没错,但这样做“快50%”并不意味着完成比赛快50%。所以可能是“不成熟和不相关的优化”。也就是说,如果你能解释这如何构成一个显著的(真正的)优势,我非常愿意接受我的话和+1。我的立场是,就性能而言,其中一个并不(明显)比另一个更具优势,但sysfs one的实现更为灵活,用户友好度更高。因此,我认为ioctl优于sysfs的选择与您每秒访问接口的次数成正比(更少的sysfs/更多的ioctl),但是在某个时候,如果你访问的内容太多,也许最好重新考虑一下设计,并将其保留在内核空间中,我想即使是在uClinux上下文切换上,也要付出代价。