Mic*_*l P 60 c linux embedded performance dev-null
我们有一个包含大量打印消息的守护进程.由于我们正在开发具有弱CPU和其他约束硬件的嵌入式设备,因此我们希望在最终版本中最小化printf消息的任何类型的成本(IO,CPU等).(用户没有控制台)
我的队友和我有分歧.他认为我们可以将所有内容重定向到/ dev/null.它不会花费任何IO,所以感情将是最小的.但我认为它仍将花费CPU,我们最好为printf定义一个宏,这样我们就可以重写"printf"(也许只是返回).
所以我需要一些关于谁是对的意见.Linux是否足够聪明以优化printf?我真的很怀疑.
iBu*_*Bug 71
差不多.
当您将程序的stdout重定向到时/dev/null,任何调用printf(3)仍将评估所有参数,并且字符串格式化过程仍将在调用之前进行write(2),这会将完整格式化的字符串写入进程的标准输出.在内核级别,数据不会写入磁盘,而是由与特殊设备关联的处理程序丢弃/dev/null.
所以在最好的情况下,你不会绕过或逃避评估参数并传递它们的开销,printf后面的字符串格式化工作printf,以及至少一个实际写入数据的系统调用,只需将stdout重定向到/dev/null.嗯,这是Linux的真正区别.实现只返回您想要写入的字节数(由您调用的第3个参数指定write(2))并忽略其他所有内容(请参阅此答案).根据您正在编写的数据量以及目标设备(磁盘或终端)的速度,性能差异可能会有很大差异.在嵌入式系统中,一般来说,通过重定向来切断磁盘写入/dev/null可以为非常少量的写入数据节省相当多的系统资源.
虽然从理论上讲,程序可以/dev/null在符合标准(ISO C和POSIX)的标准限制内检测并执行某些优化,但基于对常见实现的一般理解,它们实际上没有(即我不知道任何Unix或Linux)系统这样做).
POSIX标准强制要求对任何调用的标准输出进行写入printf(3),因此write(2)根据相关的文件描述符,它不符合标准 - 禁止调用.有关POSIX要求的更多详细信息,您可以阅读Damon的答案.哦,快速说明:所有Linux发行版都符合POSIX标准,尽管没有被证明是这样的.
请注意,如果printf完全更换,某些副作用可能会出错,例如printf("%d%n", a++, &b).如果你真的需要根据程序执行环境来抑制输出,可以考虑设置一个全局标志并包装printf以在打印前检查标志 - 它不会使程序变慢到可见性能损失的程度,因为单个条件检查比调用和执行所有字符串格式化要快得多printf.
Dam*_*mon 41
该printf函数将写入stdout.它不符合优化/dev/null.因此,您将有解析格式字符串和评估任何必要参数的开销,并且您将至少有一个系统调用,另外您将缓冲区复制到内核地址空间(与系统调用的成本相比,这是可忽略的) .
这个答案基于POSIX的具体文档.
系统接口
dprintf,fprintf,printf,snprintf,sprintf - 打印格式化输出fprintf()函数应将输出放在命名输出流上.printf()函数应将输出放在标准输出流stdout上.sprintf()函数应将输出后跟空字节'\ 0'放在从*s开始的连续字节中; 用户有责任确保有足够的空间.
基本定义
应
对于符合POSIX.1-2017的实现,描述必需的功能或行为.应用程序可以依赖于特征或行为的存在.
Som*_*ude 10
该printf函数写入stdout.如果连接到的文件描述符stdout被重定向到/dev/null那么没有输出将被写入任何地方(但它仍将被写入),但是printf对它自己的调用和它所做的格式化仍然会发生.
使用printf()源作为指导来编写自己的包装printf(),如果设置了noprint标志,则立即返回.这样做的缺点是,实际打印时会因为必须解析格式字符串两次而消耗更多资源.但是在不打印时它使用的资源可以忽略不计.不能简单地替换printf(),因为printf()中的底层调用可以使用较新版本的stdio库进行更改.
void printf2(const char*formatstring,...);
| 归档时间: |
|
| 查看次数: |
4934 次 |
| 最近记录: |