如何使用C缓冲并向磁盘写入低延迟输入

时间:2013-11-29 11:31:05

标签: c performance low-latency

我需要编写C代码(不是C#或C ++)来从硬件分析器(通过100Mb TCP / IP网络)获取数据并将其写入磁盘。

为什么我说“低延迟”,好吧,硬件分析器有一个9KB的内部缓冲区,这是2ms的数据存储,之后它会遇到缓冲区溢出而丢失信息包。

我的应用程序能够在不丢失任何数据包的情况下获取此缓冲区,但我注意到我无法以此速率将数据写入磁盘。

我的代码如下所示:

int main (int argc, char * argv [] )
{
  pthread_t th_rx; /* Thread for receiving packets */

  outputfile = fopen ("output.log", "wb");

  link_open(); // open device link

  pthread_create ( &th_rx, NULL, read_packets, 0 );

  // running loop
  fclose (outputfile);
  pthread_exit(NULL);
  link_close(); // close device link 
  return 0; 
}

static thread_result read_packets (void *arg)
{
  char  rxbuf[40960];

  while (receiving)
  {
    bytes_received = read_packet(); //read packet from device buffer
    rxbuf = extract_data(bytes_received);
    fwrite (rxbuf, 1, bytes_received, outputfile); 
  }
  return thread_return;
}

我需要的是如何做到这一点的想法。

  • 1:收到后不写包,创建一个循环?缓冲
  • 2:创建2个线程循环缓冲区?

如何改进我的代码以及我可以做些什么来获得稳定的写入?

代码示例将非常受欢迎,因为我感到迷茫:(

由于

3 个答案:

答案 0 :(得分:2)

正如你猜对了,你应该做的第一件事是,在你从设备上阅读时不要写入磁盘。

  • 创建循环/环形缓冲区(或仅缓冲区列表)以存储从设备读取的数据。此操作足够快,因此设备内存不会填满。

    • 但是,如果设备读取是非阻塞的,您可能希望o决定休眠,以便您的循环不会占用cpu。
  • 一个线程从设备读取数据并放入缓冲区。

  • 在另一个线程中,继续将缓冲区写入磁盘。

答案 1 :(得分:1)

正如你所说,hw分析器只有9 kb的{​​{1}}内存。然后写入HDD所需的速度为2 ms。我相信测试计算机在HDD上的写入速度至少为10 Mb / s。因此,这里唯一的问题是写入具有如此大部分数据的HDD,这可以给写入足够的时间。例如,缓冲区可以是1秒或4.6 Mb。存储这样的数据部分将比从hw设备收集1s数据更快,并且“写线程”花费不超过500ms来完成其工作。在实际程序中,这个时间可能有所不同,但对于单核系统来说,它也必须足够。
因此,您可以使用两个ping-pong(一个填充来自hw的数据,一个存储到HDD)具有两个线程且没有循环缓冲区的缓冲区。因此,您可以使用producer/consumer模型,该模型已有详细描述,并且有很多示例。


答案 2 :(得分:0)

您应该研究异步I / O.但是Async-I / O API依赖于操作系统,您没有指定您正在使用的操作系统。你使用线程也没有意义。如果你想使用线程(而不是异步I / O),那么你有一个线程正在执行数据包读取,其他线程应该写入。将它们放在一个线程中就没有任何好处。