C 多线程读取文件:前置或多个FD

C 多线程读取文件:前置或多个FD,c,multithreading,performance,C,Multithreading,Performance,我有一个多线程程序,我想让每个线程从同一个文件中读取相同的数据 我从pread(2)知道它是线程安全的;然而,我关心的是速度,而不是记忆 使用pread让多个线程从同一个文件描述符读取会更快吗?或者让每个线程将自己的文件描述符读取到同一个文件并从那里读取会更快吗 我的想法是,如果pread是原子的,那么它会阻止另一个线程同时读取;但是,如果有很多线程,每个线程都有自己的fd,并且操作系统需要为每次读取提供服务,那么所有的上下文切换可能会占用更多的时间。有相同的要求,我为此做了一个测试。根据对SS

我有一个多线程程序,我想让每个线程从同一个文件中读取相同的数据

我从
pread(2)
知道它是线程安全的;然而,我关心的是速度,而不是记忆

使用
pread
让多个线程从同一个文件描述符读取会更快吗?或者让每个线程将自己的文件描述符读取到同一个文件并从那里读取会更快吗


我的想法是,如果
pread
是原子的,那么它会阻止另一个线程同时读取;但是,如果有很多线程,每个线程都有自己的fd,并且操作系统需要为每次读取提供服务,那么所有的上下文切换可能会占用更多的时间。

有相同的要求,我为此做了一个测试。根据对SSD和HDD的测试,
pread-提高读取速度,但如果写入时使用相同的FD,写入速度会变慢。
读取(使用单独的FD)-读取操作比pread慢。但它不影响写操作(使用单独的FD完成)

所以最好的选择是

  • 使用单独的FD进行写入(仅写模式)
  • 打开单个FD(只读模式),并使用pread跨多个线程使用它

SSD上的结果(读/写计数10000000)

- 前置(与用于写入和读取的FD相同) 使用不同的FD读取 阅读 25秒+ 27秒+ 写 38秒+ 33秒+
出于同样的要求,我做了一个测试。根据对SSD和HDD的测试,
pread-提高读取速度,但如果写入时使用相同的FD,写入速度会变慢。
读取(使用单独的FD)-读取操作比pread慢。但它不影响写操作(使用单独的FD完成)

所以最好的选择是

  • 使用单独的FD进行写入(仅写模式)
  • 打开单个FD(只读模式),并使用pread跨多个线程使用它

SSD上的结果(读/写计数10000000)

- 前置(与用于写入和读取的FD相同) 使用不同的FD读取 阅读 25秒+ 27秒+ 写 38秒+ 33秒+
与任何其他性能问题一样,要做的是对这两种方法进行分析和测量,以进行比较。这也是回答你自己问题的最好方法。@kaylum我是想使用gprof或valgrind之类的东西,还是他们基本上在做相同的事情?大概文件相当大,不同的线程对数据做不同的处理。内核缓冲池将磁盘块保留在内存中,这样当一个线程从磁盘读取块时,其他线程将从内核缓冲池中已有的块中获益(除非内存压力和/或磁盘活动过大)。你可能只关心整个过程的时间;您可能不需要对处理文件所用的时间进行粗略测量。我的最佳猜测是,多个
open()
调用和多个
pread()
调用之间不会有太大区别。如果有什么区别的话,多个文件描述符将简化代码(减少错误定位的机会),因此您将以这种方式获胜。但是如果你真的担心的话,测量是得到一个好答案的唯一方法,但是记住,答案可能在不同的硬件上有所不同。在上下文切换方面没有显著差异;
read()
pread()
调用都需要上下文切换。文件是否适合RAM?您的处理运行多长时间?这实际上是
mmap()
的最佳用例之一,尤其是当文件适合RAM并且处理是长时间运行且读密集型的时。在多个描述符上的
read()。在Linux上,
pread()
read()
都能快速到达
vfs\u read()
,但是
read()
也需要读取,然后设置文件位置。与任何其他性能问题一样,要做的事情是对这两种方法进行分析和测量,以进行比较。这也是回答你自己问题的最好方法。@kaylum我是想使用gprof或valgrind之类的东西,还是他们基本上在做相同的事情?大概文件相当大,不同的线程对数据做不同的处理。内核缓冲池将磁盘块保留在内存中,这样当一个线程从磁盘读取块时,其他线程将从内核缓冲池中已有的块中获益(除非内存压力和/或磁盘活动过大)。你可能只关心整个过程的时间;您可能不需要对处理文件所用的时间进行粗略测量。我的最佳猜测是,多个
open()
调用和多个
pread()
调用之间不会有太大区别。如果有什么区别的话,多个文件描述符将简化代码(减少错误定位的机会),因此您将以这种方式获胜。但是如果你真的担心的话,测量是得到一个好答案的唯一方法,但是记住,答案可能在不同的硬件上有所不同。在上下文切换方面没有显著差异;
read()
pread()
调用都需要上下文切换。文件是否适合RAM?您的处理运行多长时间?这实际上是
mmap()
的最佳用例之一,尤其是当文件适合RAM并且处理是长时间运行且读密集型的时。在多个描述符上的
read()
和一个描述符上的
pread()
之间,