多线程递归程序c++
Posted
技术标签:
【中文标题】多线程递归程序c++【英文标题】:Multihreading recursive program c++ 【发布时间】:2015-01-20 06:15:01 【问题描述】:我正在研究一种递归算法,我们希望对其进行并行化以提高性能。
我使用 Visual c++ 12.0 和
如果我做错了什么以及我应该对代码进行哪些更正,请告诉我。
这是我的代码
void nonRecursiveFoo(<className> &data, int first, int last)
//process the data between first and last index and set its value to true based on some condition
//no threads are created here
void recursiveFoo(<className> &data, int first, int last)
int partitionIndex = -1;
data[first]=true;
data[last]=true;
for (int i = first + 1; i < last; i++)
//some logic setting the index
If ( some condition is true)
partitionIndex = i;
//no dependency of partitions on one another and so can be parallelized
if( partitionIndex != -1)
data[partitionIndex]=true;
//assume some threadlimit
if (Commons::GetCurrentThreadCount() < Commons::GetThreadLimit())
std::thread t1(recursiveFoo, std::ref(data), first, index);
Commons::IncrementCurrentThreadCount();
recursiveFoo(data, partitionIndex , last);
t1.join();
else
nonRecursiveFoo(data, first, partitionIndex );
nonRecursiveFoo(data, partitionIndex , last);
//主要
int main()
recursiveFoo(data,0,data.size-1);
//共同点
std::mutex threadCountMutex;
static void Commons::IncrementCurrentThreadCount()
threadCountMutex.lock();
CurrentThreadCount++;
threadCountMutex.unlock();
static int GetCurrentThreadCount()
return CurrentThreadCount;
static void SetThreadLimit(int count)
ThreadLimit = count;
static int GetThreadLimit()
return ThreadLimit;
static int GetMinPointsPerThread()
return MinimumPointsPerThread;
【问题讨论】:
这段代码可以编译和工作吗?如果是这样,您应该尝试在 codereview 网站上发布此内容:codereview.stackexchange.com 你不应该依赖阅读线程看到更新到CurrentThreadCount
,当他们没有锁定他们的读取访问权限时;使用 atomic_int 会更好。无论如何,我建议您添加一些日志记录,以向您展示线程实际上是如何划分工作的。是否可以期望更快还取决于您正在处理的数据量:太少和线程创建的开销将使收益相形见绌。实际上,如果您的分区不能平均分配工作,您最终可能会得到一些运行时间很短的线程,而 1 或 2 最终会同步完成大部分工作。
仅仅因为你的代码线程化并不意味着它更快。在分析单线程代码方面做了什么?
这可能有多种原因,但首先: thd 程序 rougvmy 是如何运行 lonc 的?你有多少数据项?你有几个核心?你的线程数限制是多少?
你用什么编译器?
【参考方案1】:
如果没有更多信息(参见 cmets),这主要是猜测,但您应该注意以下几点:
首先,确保您的分区逻辑与处理相比非常短且快速。否则,您只是创造了比获得处理能力更多的工作。 确保有足够的工作开始,否则加速可能不足以支付线程创建的额外开销。 检查您的工作是否在不同线程之间均匀分布,并且生成的线程数不要超过计算机上的内核数(最后打印总线程数 - 不要依赖您的ThreadLimit
)。
不要让您的分区变得太小(尤其是不少于 64 字节),否则您最终会出现错误共享。
将CurrentThreadCount
实现为std::atomic<int>
会更高效,在这种情况下您不需要互斥体。
将计数器的增量放在线程创建之前。否则,即使已达到最大线程数,新创建的线程可能会在计数器递增之前读取计数器并再次生成一个新线程(这仍然不是一个完美的解决方案,但我只会在这方面投入更多时间,如果您已经验证,过度使用是您的实际问题)
如果您确实必须使用互斥锁(出于示例代码之外的原因),您必须在每次访问CurrentThreadCount
(读写访问)时使用它。否则,严格来说,这是一种竞争条件,因此是 UB。
【讨论】:
【参考方案2】:通过使用t1.join
,您基本上是在等待另一个线程完成 - 即不并行执行任何操作。
通过查看您的算法,我看不出如何通过使用线程来并行化(从而改进)它 - 您必须等待单个递归调用结束。
【讨论】:
【参考方案3】:首先,您不会并行执行任何操作,因为每个线程创建都会阻塞,直到创建的线程完成。因此,您的多线程代码总是比非多线程版本慢。
为了实现并行化,您可以为调用非递归函数的那部分生成线程,将线程 ID 放入向量中,并通过遍历向量在递归的***别加入。 (虽然有更优雅的方法可以做到这一点,但我认为第一次应该可以)。
因此,所有非递归调用将并行运行。但是你应该使用另一个条件而不是最大线程数,而是问题的大小,例如last-first<threshold
.
【讨论】:
以上是关于多线程递归程序c++的主要内容,如果未能解决你的问题,请参考以下文章
如果 ANSI C++ 不支持多线程,非托管 C++ 应用程序如何实现多线程?