1

我正在尝试在 Visual C++ 中实现多线程、递归文件搜索逻辑。逻辑如下:线程 1,2 将从目录位置开始,并将目录中存在的文件与搜索条件进行匹配。如果他们找到子目录,他们会将其添加到工作队列中。一旦线程完成了目录中的文件,它就会从工作队列中获取另一个目录路径。工作队列是一个 STL Stack 类,由用于 push()、pop()、top() 调用的 CriticalSections 保护。

如果堆栈在任何时候为空,线程将在重试之前等待一分钟。此外,当所有线程都处于等待状态时,搜索被标记为完成。

这个逻辑没有任何问题,但我觉得我没有获得使用线程的全部潜力,因为与使用单线程相比没有显着的性能提升。我觉得工作堆栈是瓶颈,但无法弄清楚如何消除锁定部分。我尝试了另一种变体,其中每个线程将拥有自己的堆栈,并且仅当本地堆栈大小超过固定数量的工作项时,才会将工作项添加到全局堆栈。如果本地堆栈为空,线程将尝试从全局队列中获取。即使有这种变化,我也没有发现明显的差异。有没有人对改进同步逻辑有任何建议。

问候,

4

2 回答 2

2

我真的怀疑你的工作堆栈是瓶颈。磁盘只有一个磁头,一次只能读取一个数据流。只要您的线程处理数据的速度与磁盘可以提供的速度一样快,那么您可以做的其他事情就不会对整体速度产生任何重大影响。

对于其他类型的任务,您的队列可能会成为一个重要的瓶颈,但对于这个任务,我对此表示怀疑。请记住此处操作的时间尺度。在 CPU 内部发生的一个简单操作需要不到一纳秒的时间。从主存储器读取需要几十纳秒的时间。诸如线程切换或同步之类的事情大约需要几百纳秒左右。磁盘驱动器上的单个磁头移动大约需要一毫秒(1,000,000 纳秒)。

于 2010-08-28T19:07:05.737 回答
1

除了@Jerry 的回答,你的瓶颈是磁盘系统。如果您有一个 RAID 阵列,您可能会看到使用 2 或 3 个线程的一些适度改进。

如果您必须搜索多个驱动器(注意:物理驱动器,而不是单个物理驱动器上的卷),您可以为每个驱动器使用额外的线程。

于 2010-08-28T19:22:25.283 回答