C++ 其中;级别“;多线程最有效吗?

C++ 其中;级别“;多线程最有效吗?,c++,multithreading,algorithm,C++,Multithreading,Algorithm,请原谅我使用了“级别”这个词,但我不知道该怎么称呼它。我正在写一个游戏引擎。此游戏引擎加载操作所需的大量文件。这些文件大多是档案,其中包含大量文件。这些文件被单独分解为zlib压缩块 我的问题是我应该在哪个级别实现多线程 为了便于讨论,让我们说: 15个存档文件(每个10mb) 每个存档中有20个文件(0.5mb) 每个文件由数百个压缩块组成 我意识到,如果我在块膨胀级别执行,它将平均分配任务,并且如果有非常大的文件,就不会有瓶颈检查。但是我冒着创建太多线程的风险 编辑:我应该澄清一下,我理解从

请原谅我使用了“级别”这个词,但我不知道该怎么称呼它。我正在写一个游戏引擎。此游戏引擎加载操作所需的大量文件。这些文件大多是档案,其中包含大量文件。这些文件被单独分解为zlib压缩块

我的问题是我应该在哪个级别实现多线程

为了便于讨论,让我们说:

15个存档文件(每个10mb)

每个存档中有20个文件(0.5mb)

每个文件由数百个压缩块组成

我意识到,如果我在块膨胀级别执行,它将平均分配任务,并且如果有非常大的文件,就不会有瓶颈检查。但是我冒着创建太多线程的风险


编辑:我应该澄清一下,我理解从磁盘执行多线程I/O不会有太大帮助。对于我的问题,我主要是询问这些文件在不同级别上的处理和解析。假设I/O已经被处理,我只是担心解析这些文件。

一般来说,运行的线程不要超过逻辑CPU。你不能跑得更快,你只是引入了开销

除非您有一些特定情况需要更专业的处理,否则我建议您只创建一个线程池(executors==CPU的数量),然后为每种情况创建一个运行程序/调度程序—一个是将归档安排为作业,另一个是将文件安排为作业。使用性能更好的解决方案


如果不知道您的代码是什么样子的,我怀疑您能否得到更清楚的答案。

如果您的代码是绑定到单个磁盘驱动器的I/O,那么它可能会对多线程产生反作用。您需要计算出程序读取文件所需的时间以及处理数据所需的时间

如果大部分时间用于从磁盘读取数据,那么多线程对您没有多大帮助


如果大部分时间用于数据处理,那么每个核心1个线程是一个很好的经验法则,但是您应该将读取部分留给单个线程,将处理部分留给每个代码1个线程的池(即单生产者多消费者设计)。

如果我理解您的问题,您的问题是,是否应该为每个存档文件或存档中的每个文件使用线程,甚至更低

如果是这样的话,我想我们不能给你一个答案。首先,您需要多线程吗?你给出的数字并不令人印象深刻,它看起来应该运行足够快,只有一个线程

如果没有,我建议您实现最简单的多线程级别,即顶层(对于每个归档文件都是如此),然后再次查看是否需要更高的性能


如果是,则执行其他级别和措施。有太多不同的因素需要事先知道。如果没有,您可以做其他事情:-)

当您的工作单元太大/太粗糙时,您可能不会使所有CPU饱和,或者在处理最后一个项目时,一些CPU可能会空闲,等待完成缓慢的项目

当工作单元太小时,分配工作和合并结果的开销太大

通常,最快的方法是使用从开销角度来看可以接受的最小大小/级别

在架构上,在更高级别上执行并行通常更容易,因为您可以一次性自动并行化调用图的整个子树


这些都是权衡。你需要为你的特殊情况做出决定。听起来在文件级并行化是正确的方法。它为您提供了15*20=300个工作项,通常分布在4-8个核上。这是一个很好的分配比率。

10mb的数据?在没有多线程的情况下处理这些需要多长时间?不要创建比可用内核更多的线程,那样会适得其反。正如@Lucas Trzesniewski上面所说的,没有比可用内核更多的线程。根据“任务”(例如,要做的事情)和可以分配“任务”的工作线程来思考您的问题。将线程复杂性保持在最低限度,记住,逻辑上并行的事情越多,正确测试代码就越困难。首先问问你自己-线程的好处是什么?如果我不使用它,会对事情产生多大的影响。尝试所有三个版本(同时使用完全存档或块),并测量结果。就我个人而言,如果可能的话,我会选择块,因为它看起来会更优雅地缩放(取决于ofc的细节)。“但我会冒创建太多线程的风险。”-线程池可以消除这种特殊风险,但是如果工作过于精细,你仍然会有不必要的开销。我打算在评论中提到这个答案,因为OP谈到了开发游戏引擎。。我知道许多消费者级笔记本电脑没有最好(或大多数碎片整理)的硬盘驱动器。我没有考虑对实际的I/O输入进行多线程处理。这将只考虑这些文件的解析和处理。单生产者读取数据,线程池处理数据。线程池大小=核心计数。@txtechhelp实际上,如果您有旋转磁盘,多线程从碎片驱动器读取不同的文件可能是一个好主意。如果您将8个请求排队,驱动器会发现是否有比逐个读取更快的方法来提供请求。再说一次,在这种情况下(10mb),这几天不太重要。