示例代码:
#include <stdio.h>
#include <unistd.h>
#include <sched.h>
#include <pthread.h>
int
main (int argc, char **argv)
{
unsigned char buffer[128];
char buf[0x4000];
setvbuf (stdout, buf, _IOFBF, 0x4000);
fork ();
fork ();
pthread_t this_thread = pthread_self ();
struct sched_param params;
params.sched_priority = sched_get_priority_max (SCHED_RR);
pthread_setschedparam (this_thread, SCHED_RR, ¶ms);
while (1)
{
fwrite (&buffer, 128, 1, stdout);
}
}
该程序打开4个线程,并在stdout上输出“缓冲区”的内容,该内容是64位CPU上的128个字节或16个长整数。
如果我随后运行:
./ writetest | pv -ptebaSs 800G> / dev / null
我的速度约为7.5 GB / s。
顺便说一句,这与我得到的速度相同:
$ mkfifo out
$ dd if=/dev/zero bs=16384 >out &
$ dd if=/dev/zero bs=16384 >out &
$ dd if=/dev/zero bs=16384 >out &
$ dd if=/dev/zero bs=16384 >out &
pv <out -ptebaSs 800G >/dev/null
有什么方法可以使速度更快? 注意。 实际程序中的缓冲区未填充零。
我的好奇心是了解单个程序(经过重复处理或多进程)可以输出多少数据
好像有4个人不明白这个简单的问题。 我什至大胆地提出了问题的原因。
答案 0 :(得分:1)
首先,您需要确定您的速率限制因素。可能是cpu /内存速度,cpu /系统调用延迟,管道实现,stdio实现。可能还有更多,但这是一个好的开始:
cpu /内存-测试能快速存储一堆零的速度。
cpu / syscall-通过向/ dev / null写入1byte来测试在系统上进行简单写入所需的时间
管道实现-有点类似,但是您可以尝试改变管道容量(如果您使用的是Linux,则为fcntl(2)F_GETPIPE_SZ。F_SETPIPE_SZ)。
stdio实现-用write替换fwite / setbuf。我建议将写入大小与管道容量/数量进程对齐可能会产生良好的结果,但您可能应该进行更广泛的研究。
通过多个过程尝试上述所有方法,尽管您可能需要放大memcpy才能获得有意义的结果。
使用这些数字,您应该能够计算出最大吞吐量。请报告,我相信有很多人对此感兴趣。
答案 1 :(得分:0)
看来,Linux调度程序和IO优先级在减速中起了很大的作用。
此外,幽灵和其他CPU漏洞缓解措施也开始发挥作用。
进一步优化后,为了获得更快的速度,我不得不调整以下内容:
{
"Message": "No HTTP resource was found that matches the request URI 'http://localhost:63575/api/register/simple'.",
"MessageDetail": "No action was found on the controller 'Register' that matches the request."
}
现在程序输出(在同一台计算机上)为8.00 GB /秒!
如果您有其他想法,欢迎您提供帮助。
答案 2 :(得分:-1)
您的程序要做的是:
fwrite
。只是将数据从buffer
复制到buf
。buf
填满,就会调用write
。要加快速度,请避免在步骤1和fwrite
中复制该副本,并直接使用write
syscall。例如:
char buf[0x4000];
for(;;)
write(STDOUT_FILENO, buf, sizeof buf); // Implement error handling.
您可能还希望将buf
增大,以最大程度地减少系统调用的次数(减轻频谱干扰使系统调用的成本更高)。