我对多线程(Openmp和C代码)有疑问。
我将在给定文本文件中的16个不同单词后执行搜索。这样做的方法是创建一个for循环,该循环遍历包含要搜索的每个单词的数组。 16个不同的单词表示可以同时运行的16个不同的线程。使用多线程的另一种方法是将文本文件切割成x个类似大小的块,并同时搜索每个块。 我的问题是:我可以使用多线程为每个单词创建一个线程,然后将该特定子线程拆分为新的子线程,以扫描一个大小的数据块吗?
如果这不可能/不可行,我想唯一的解决方案是手动将文本文件拆分成不同的char数组,然后对我要搜索的每个单词使用#pragma。
只会对文本文件执行读取操作,并且写入操作仅限于分配给每个单词的变量,用于计算purpouses。即没有比赛条件,除非我错过了什么。
答案 0 :(得分:0)
首先,16个单词并不意味着16个不同的主题。每个线程本身都会带来诸如同步开销,不均等的工作分配,产生 - 放松时间等因素,如果不仔细研究,将导致完全损害并行性的好处。
在工作数据之间缺乏依赖性的情况下,可以极大地利用并行性。您的工作与您所表达的任何可能解决方案中的工作数据无关。要在大字符池中查找某些字符,与字符的排列无关(例如,在每个“C”之后查看“++”与查找“++”)。
现在的问题是如何利用内存带宽以及如何通过“分支预测”来消除丢失。
公共数据不同的线程在内存限制情况下非常好。第一个读取数据的线程会将其加载到缓存中,而其他线程最终会利用这一块数据。因此,数据只能从内存中加载一次。拆分数据也会导致仅从内存中加载一次数据,因为每个线程都会加载其部分然后刷新。因此,在两种情况下,内存负载都非常相似。
您的代码称为“逻辑绑定”。分支预测是非常重要的方面,但是非常棘手。公共数据模块很可能失败。假设您必须在百万球中找到红色球。预测倾向于选择“不存在”。但是说它在前100个球中失败了,在这次失败之后所有处理过的球都将以重做结束,你又回到原点。相反,在分裂的情况下,“重做”的最坏情况不会像普通数据那样糟糕。但我们无法保证。
选择上述任何模块完全取决于您所使用的架构。
SMT /逻辑核心与物理核心。使用上述任何一种SMT方法都会导致性能降低,同样不会。物理核心。 您对一个线程分裂为子线程的想法是SMT的基础。每个新线程都会增加追逐资源的同步开销,并且还可能出现分支错误预测。如果物理线程增加,分支预测会限制性能。
拆分或公共数据,您的代码不可扩展。最好的办法是尽量少用。可用的物理核心。通用数据带来的复杂性较低,应该非常容易处理。最低号码线程可以通过实验找到。在此值之后,性能将保持不变。