gpt4 book ai didi

c++ - 如何让线程等待条件执行操作而不使用过多的 CPU 时间?

转载 作者:行者123 更新时间:2023-12-02 10:12:27 27 4
gpt4 key购买 nike

我一直在尝试在矩阵运算中使用线程来使其更快地处理大型矩阵(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 时间只是为了继续检查代码。任何人都知道这是否真的如此,如果是这样,我该如何解决?

最佳答案

这里的问题叫做busy waiting .如评论中所述,您将要使用 std::condition_variable , 像这样:

std::mutex mutex;
std::condition_variable cv;
while (!flaguGkill[bgx]) {
{
unique_lock<mutex> lock(mutex); // aquire mutex lock as required by condition variable
cv.wait(lock, [this]{return flaguG[bgx];}); // thread will suspend here and release the lock if the expression does not return true
}

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;

}
注: [this] { return flaguG[bgx];} 部分,您可能需要根据这些变量的范围更改捕获参数( [] 中的位)
在您将其设置为 true 的地方,您需要调用
for (int k = 0; k < NT; k++)
{
flaguG[k] = true;
cv.notify_one();
}

// you can then use another condition variable here

关于c++ - 如何让线程等待条件执行操作而不使用过多的 CPU 时间?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63022686/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com