gpt4 book ai didi

C++ 重用调用相同函数的线程 vector

转载 作者:行者123 更新时间:2023-11-30 05:07:44 25 4
gpt4 key购买 nike

我想重用一个线程 vector ,这些线程使用不同的参数多次调用相同的函数。没有写入(原子参数除外),因此不需要互斥锁。为了描述这个想法,我创建了一个基本的并行代码示例,用于查找 vector 的最大值。显然有更好的方法来找到一个 vector 的最大值,但为了解释和避免深入了解我正在编写的真实代码的更多细节,我将使用这个愚蠢的例子。

代码通过调用函数 pFind 来查找 vector 的最大数,该函数检查 vector 是否包含数 k(k 是用上限初始化)。如果是,则停止执行,否则 k 减一并重复该过程。

下面的代码生成一个线程 vector ,并行搜索 vector 中的 k。问题在于,对于 k 的每个值,都会重新生成线程 vector ,并且每次都会加入新线程。每次生成线程 vector 并连接它们都会带来我想避免的开销。

我想知道是否有一种方法可以只生成一次线程 vector (池)并将它们重新用于新的执行。任何其他加速技巧将不胜感激。

void pFind(
vector<int>& a,
int n,
std::atomic<bool>& flag,
int k,
int numTh,
int val
) {
int i = k;

while (i < n) {
if (a[i] == val) {
flag = true;
break;
} else
i += numTh;
}
}

int main() {
std::atomic<bool> flag;
flag = false;
int numTh = 8;
int val = 1000;
int pos = 0;

while (!flag) {
vector<thread>threads;
for (int i = 0; i < numTh; i++){
thread th(&pFind, std::ref(a), size, std::ref(flag), i, numTh, val);
threads.push_back(std::move(th));
}
for (thread& th : threads)
th.join();

if (flag)
break;

val--;

}
cout << val << "\n";
return 0;
}

最佳答案

构造后无法将不同的执行函数(闭包)分配给 std::thread。这通常适用于所有线程抽象,尽管实现通常会尝试在内部内存或缓存较低级别的抽象以使线程 fork 和快速连接,因此仅构造新线程是可行的。系统编程界存在争论,即创建一个新线程是否应该非常轻量级,或者是否应该将客户端编写为不那么频繁地 fork 线程。 (鉴于这已经持续了很长时间,应该清楚其中涉及很多权衡。)

还有很多其他的抽象试图做你真正想做的事情。它们的名称包括“线程池”、“任务执行器”(或简称“执行器”)和“ future ”。它们都倾向于通过创建一些线程集(通常与系统中的硬件内核数量相关)来映射到线程,然后让每个线程循环并查找请求。

如评论所示,您自己执行此操作的主要方法是让线程具有顶层循环,该循环接受执行请求、处理它们,然后发布结果。为此,您需要使用其他同步方法,例如互斥锁和条件变量。如果有很多请求并且请求不是非常大,那么以这种方式做事通常会更快。

尽管标准 C++ 并发支持是一件好事,但对于现实世界的高性能工作来说,它也相当缺乏。类似于 Intel's TBB更像是一种工业强度的解决方案。

关于C++ 重用调用相同函数的线程 vector ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47171107/

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