c - 将子线程拆分为新的子线程 (Openmp)

标签 c multithreading multiprocessing openmp pragma

我有一个关于多线程(Openmp 和 C 代码)的问题。

我要在给定文本文件中搜索 16 个不同的词。实现它的方法是创建一个 for 循环,遍历包含要搜索的每个单词的数组。 16 个不同的字意味着可以同时运行 16 个不同的线程。另一种使用多线程的方法是将文本文件分成 x 个大小相似的 block 并同时搜索每个 block 。 我的问题是:我可以使用多线程为每个单词创建一个线程,然后将该特定的子线程拆分为新的子线程来扫描一个大小的数据 block 吗?

如果这不可能/不可行,我想唯一的解决方案是手动将文本文件拆分为不同的字符数组,然后对我要搜索的每个单词使用#pragma。

只会对文本文件执行读取操作,而写入操作仅限于分配给每个单词的变量以用于计数目的。 IE。不会有竞争条件,除非我错过了什么。

最佳答案

首先,16 个词并不意味着 16 个不同的线程。每个线程本身都会带来同步开销、不平等的工作分配、spawn-relax 时间等因素,如果不仔细考虑,将导致完全损害并行性的好处。

在工作数据之间不存在依赖性的情况下,可以极大地利用并行性。您的工作独立于您所表达的任一可能解决方案中的工作数据。要在大量字符中查找某些字符,与字符排列无关(例如,在每个“C”之后查找“++”与查找“++”)。

现在的问题是如何利用内存带宽以及如何通过“分支预测”来解决丢失的问题。

Common Data Different threads 在内存受限的情况下非常好。第一个读取数据的线程会将其加载到缓存中,而其他线程将最终使用这 block 数据。所以数据只会从内存中加载一次。拆分数据也将导致只从内存中加载一次数据,因为每个线程都会加载它的部分,然后刷新出来。因此,两种情况下的内存负载非常相似。

您的代码称为“逻辑绑定(bind)”。分支预测是需要处理的非常重要的方面,但非常棘手。公共(public)数据模块很可能会失败。假设您必须在一百万个球中找到一个红色球。预测将倾向于做出“不存在”的自然选择。但是如果说它在前 100 个球内失败了,那么在这次失败之后所有处理过的球将最终重做并且你回到原点。相反,在拆分的情况下,“重做”的最坏情况不会像普通数据那样糟糕。但我们不能保证这一点。

然后,选择上述任何模块完全取决于您可以使用的架构。

SMT/逻辑核心与物理核心。将上述任何一种方法与 SMT 一起使用都会导致性能降低 w.r.t 相同。物理核心。 您将一个线程拆分为多个子线程的想法 是 SMT 的基础。每个新线程都会增加追逐资源,带来同步开销以及分支预测错误的可能性。在增加物理线程的情况下,分支预测会限制性能。

Splitting or Common data,你的代码是不可扩展的。最好的办法是使用最小号。可用的物理内核。通用数据带来的复杂性较低,并且应该很容易处理。最小号的线程可以通过实验找到。在此值之后,性能将保持不变。

关于c - 将子线程拆分为新的子线程 (Openmp),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16265751/

相关文章:

c++ - 为什么以下代码在 C 、 C++ 中给出不同的输出?

c - 如何向 ISO 技术委员会提交变更或要求澄清

java - Java 中的监视、通知和notifyall

python - 在 multiprocessing.Pool 中设置每个进程的 niceness

c - 在 Unix 上查找已编译库的依赖项

c - Windows 函数 ReadFile 一直返回 FALSE,不知道为什么

Java多线程任务

c# - 多线程.NET队列问题

python - SCons 中 chdir=1 和 num_jobs>1 的组合

python - 使用python的并行数值积分