C++ 我是否应该根据CPU的数量将异步调用划分为块?
在8处理器计算机上考虑此脚本:C++ 我是否应该根据CPU的数量将异步调用划分为块?,c++,asynchronous,C++,Asynchronous,在8处理器计算机上考虑此脚本: int parallel_function(int i){ system(some_complex_and_long_call); return i; } int main() { // Parallel run std::vector<std::future<int>> futures; for(int i = 30; i > 0; i--) { futures.push_b
int parallel_function(int i){
system(some_complex_and_long_call);
return i;
}
int main() {
// Parallel run
std::vector<std::future<int>> futures;
for(int i = 30; i > 0; i--) {
futures.push_back (std::async(std::launch::async, parallel_function, i));
}
std::cout << "Stuff submitted" << std::endl;
for(auto &e : futures) {
std::cout << e.get() << std::endl;
}
return 0;
}
int并行函数(int i){
系统(一些复杂的调用和长调用);
返回i;
}
int main(){
//平行运行
向量期货;
对于(int i=30;i>0;i--){
futures.push_back(std::async(std::launch::async,parallel_函数,i));
}
std::cout一般来说,如果线程受CPU限制,那么每个物理核心1个线程可能是最好的,原则上每个线程一个任务可以最大限度地减少管理任务而不是执行实际工作所花费的时间
这假设您的任务(异步parallel_函数
调用)都需要大约相同的时间才能完成。如果不是这样,您需要更多的任务来保持第一个完成核心的繁忙状态
如果运行需要一个月的时间(这是相关信息,应该在问题中),我怀疑24个可避免的同步操作是否会产生很大的影响
如果你的调度程序做了更多的上下文切换,它可能真的会减慢一切,但我不知道你的平台或情况是否如此
看到上面所有的ifs和handwaving了吗?它们转化为:
tl;dr可能。可能。取决于很多东西。为什么不试试看呢?不管互联网告诉你什么,这是唯一可以确定的方法。一般来说,每个物理核心一个线程可能是最好的,如果线程是CPU限制的,原则上每个线程一个任务可以最大限度地减少管理任务而不是做家务的时间实际工作
这假设您的任务(异步parallel_函数
调用)都需要大约相同的时间才能完成。如果不是这样,您需要更多的任务来保持第一个完成核心的繁忙状态
如果运行需要一个月的时间(这是相关信息,应该在问题中),我怀疑24个可避免的同步操作是否会产生很大的影响
如果你的调度程序做了更多的上下文切换,它可能真的会减慢一切,但我不知道你的平台或情况是否如此
看到上面所有的ifs和handwaving了吗?它们转化为:
tl;dr可能。可能。取决于很多东西。为什么不试试看呢?不管互联网告诉你什么,这是唯一确定的方法。这确实取决于std:async
的实现
如果某些复杂的和长的调用确实是CPU受限的任务,那么将线程数作为(逻辑)内核数似乎是合理的
GCC实际上会为每个std::async
调用生成一个线程,因此您可能不想过多地使用async
的GCC版本。线程的创建、调度和销毁成本很高,上下文切换会降低性能。在这种情况下,我建议您找到一个线程池实现(github上有很多)并使用线程池而不是async
在调用std::async
时,Clang和VC++都在后台使用线程池,因此如果您使用这些编译器,可以根据需要生成尽可能多的async
,底层实现将为您创建线程
另一个附带问题:我可以在async中调用void函数吗
函数必须返回什么
是的,这是可能的。在这种情况下,std:async
将返回std:future
,这实际上取决于std:async
的实现
如果某些复杂的和长的调用确实是CPU受限的任务,那么将线程数作为(逻辑)内核数似乎是合理的
GCC实际上会为每个std::async
调用生成一个线程,因此您可能不想过多地使用async
的GCC版本。线程的创建、调度和销毁成本很高,上下文切换会降低性能。在这种情况下,我建议您找到一个线程池实现(github上有很多)并使用线程池而不是async
在调用std::async
时,Clang和VC++都在后台使用线程池,因此如果您使用这些编译器,可以根据需要生成尽可能多的async
,底层实现将为您创建线程
另一个附带问题:我可以在async中调用void函数吗
函数必须返回什么
是的,这是可能的。在这种情况下,std::async
可能会返回std::future
。可能。这取决于很多东西。为什么不试试看呢?不管互联网告诉你什么,这是唯一确定的方法。@当然我可以尝试,问题是我的系统调用需要一个月才能运行(它们是昂贵的模拟)所以我认为先问可能更好:)@GáborErdős你不必告诉它是否消耗了所有的CPU资源。@xaxxon我真的不明白。正如我写的,即使一个调用也会使CPU达到100%。30个调用也是如此。根据经验,如果系统调用(进程)在cpu上连续运行,然后使用8个线程,您将获得最高性能。虽然如果您的调用有大量时间睡眠,等待其他内容,那么您可以创建更多线程并行运行。无论哪种方式,我几乎不怀疑,如果您只轮流生成8个线程,而不是全部30个线程,您将看到性能提高,因为您的操作系统将执行一些调度,大多数情况下,可能比你的日程安排好一点。可能。可能。这取决于很多东西。为什么不试试看呢?不管互联网告诉你什么,这是唯一确定的方法。@当然我可以试试,问题是我的系统调用运行大约需要一个月的时间(它们是昂贵的模拟)所以我认为先问可能更好:)@GáborErdős它不必完成,你就可以知道它是否消耗了所有的CPU资源。@xaxxon我真的不明白。正如我写的e