我目前正处于用 C 语言编写多线程程序的入门阶段。我了解如何创建具有完全独立功能的独立线程,但我想了解该领域的程序员如何分解单个任务来执行多线程的优势。我已经完成了几个同步单独线程的练习,但是在分解单个任务并使多个线程更快地完成任务时没有什么好处。在解决这些类型的问题并解释如何和为什么你会以这种特定方式解决问题时,我真的很感激一些智慧。
举个例子,假设这是我试图用多线程处理的任务。 [它将两个矩阵相乘,创建了 n x p 维度的 c 矩阵。] 还可以说我们可以输入我们想要在 1 和 t 之间运行的线程数(即使线程 >= 4 不会有显着的性能差异) ) 所以很明显如何攻击它。
for (i = 0; i < n; i++){
for (j = 0; j < p; j++){
c[i][j] = 0;
for (k = 0; k < m; k++){
c[i][j] += a[i][k] * b[k][j];
}
}
}
我的第一个想法是基本上根据线程数来划分每个循环。所以,对于 t 个线程,
for (i = 0; i < n / t; i++){
for (j = 0; j < p / t; j++){
c[i][j] = 0;
for (k = 0; k < m / t; k++){
c[i][j] += a[i][k] * b[k][j];
}
}
}
然后将它们与信号量同步。但这必须将问题的每个部分分成不重叠或遗漏任何矩阵的 t-内聚线程。这似乎有点多,我觉得有更好的方法来攻击它。你们会怎么做?
最佳答案
有 m 个运算涉及将左矩阵的一行乘以右矩阵的一列。对于 t 个线程,每个线程可以执行 m/t 操作。如果 m 不是 t 的倍数,则决定如何拆分工作。使用 m/t 意味着最后一个线程做更多的工作,使用 (m+t-1)/t 意味着最后一个线程做更少的工作,或者在某些线程上使用 (m/t)+1 操作和 (m/t) 操作在剩余的线程上。
这可能不是多线程的好案例,但至少您了解了这个概念。
这是一个基于 Windows 的多线程示例的链接,用于合并排序,使用 4 个线程可将性能提高约 3 倍。之前我以为merge函数中的关键循环太小了,进程会受内存限制,但结果是受cpu限制。
https://codereview.stackexchange.com/questions/148025/multithreaded-bottom-up-merge-sort
关于c - C中的高效多线程,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43173469/