【发布时间】:2020-07-21 20:34:49
【问题描述】:
我一直在尝试在矩阵运算中使用线程,以使其更快地处理大型矩阵 (1000x1000)。到目前为止,我已经用下面的代码取得了一些成功。与使用单线程相比,速度显着提高。
void updateG(Matrix &u, Matrix &g, int n, int bgx, int tamx, int tamy)
{
int i, j;
for (i = bgx; i < tamx; i += n)
{
for (j = 0; j < tamy; j++)
{
g(i,j, g(i,j)+ dt * 0.5 * (u(i,j) - (g(i,j) * y)));
}
}
}
void updateGt(Matrix &u, Matrix &g, int tam)strong text
{
int i;
const int n = NT;
std::thread array[n];
for (int i = 0; i < n; i++)
{
array[i] = std::thread(updateG, std::ref(u), std::ref(g), n, i, tam, tam);
}
joinAll(array, n);
}
但是,我需要在主代码中多次调用这个操作,而且每次出现这种情况都必须重新初始化线程数组,创建新线程,浪费很多时间(根据我在网上看到的那些很贵)。 因此,我开发了一种替代解决方案,只创建和初始化线程数组一次,并在每次调用函数时使用相同的线程来执行矩阵运算。使用一些标志变量,以便线程仅在必要时执行操作。就像下面的代码:
void updateG(int bgx,int tam)
{
while (!flaguGkill[bgx]) {
if (flaguG[bgx]) {
int i, j;
for (i = bgx; i < tam; i += NT)
{
for (j = 0; j < tam; j++)
{
g->operator()(i, j, g->operator()(i, j) + dt * 0.5 * (u->operator()(i, j) - (g->operator()(i, j) * y)));
}
}
flaguG[bgx] = false;
}
}
}
void updateGt()
{
for (int k = 0; k < NT; k++)
{
flaguG[k] = true;
}
for (int i = 0; i < NT; i++)
{
while(flaguG[i]);
}
}
我的问题是。这个应该更快的解决方案比第一个解决方案要慢得多,幅度很大。在我的完整代码中,我有 2 个函数,例如 updateGt 和 updateXt,每个函数使用 4 个线程,我认为问题在于,虽然该函数应该处于空闲等待状态,但它却占用了大量 CPU 时间只是为了继续检查代码。任何人都知道是否真的是这样,如果是这样,我该如何解决?
【问题讨论】:
-
您必须使用
std::mutex和std::condition_variable。在当前状态下,显示的代码是未定义的行为,它会严重崩溃只是时间问题。 -
为什么不改用 OpenMP?
-
@mpoeter 以前没研究过,这是我第一次用线程做实验,因为我刚刚读到它是一个用更简单的方式实现并发的api,对吧?如果是这样,如果这种方法根本不起作用,我可能会尝试下一个。
-
@AlanBirtles SamVarshavchik 感谢您的提示,我将阅读这些主题。令人惊讶的是它没有中断,并且输出结果与其他版本的代码相同,只是速度慢了很多。
标签: c++ multithreading