我应该分割我的异步调用块根据cpu的数量
Should i split my async calls into chunks according to the number of CPUs?
在一台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_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;
}
它将在异步中产生30个系统调用,但是我只有8个处理器,每个系统调用可以(我猜应该)使用单个处理器的100%。
是一次只运行8个调用(甚至7个,并留下处理器空闲)更好,还是没关系,我可以调用尽可能多的。哪个跑得更快,为什么?
另一个侧面问题:我可以异步调用void
函数,还是函数必须返回一些东西?
这取决于std:async
的实现。
如果some_complex_and_long_call
确实是CPU绑定任务,那么将线程数作为(逻辑)内核的数量似乎是合理的。
GCC实际上为每个std::async
调用生成一个线程,因此您可能不想过多地使用async
的GCC版本。线程的创建、调度和销毁是非常昂贵的,而且上下文切换会降低性能。在这种情况下,我建议你找到一个线程池实现(github上有很多),并使用线程池代替async
。
Clang和vc++在调用std::async
时都在后台使用线程池,所以如果你正在使用这些编译器,生成尽可能多的async
,底层实现将为你照顾线程创建。
另一个侧面问题:我可以在异步中调用void函数吗函数必须返回什么?
是的,这是可能的。在本例中,std::async
将返回std::future<void>
。
一般来说每个物理核心一个线程可能是最好的,如果线程是cpu限制的,并且原则上每个线程一个任务可以最大限度地减少管理任务而不是执行实际工作的时间。
这假设您的任务(异步parallel_function
调用)都需要大约相同的时间来完成。如果不是这种情况,您需要更多的任务来保持第一个完成的核心(s)忙碌。
如果它需要一个月的时间来运行(这是应该在问题中的相关信息),我怀疑24个可避免的同步操作会有很大的不同。
如果你的调度程序做了更多的上下文切换,它真的可能会减慢一切,但我不知道你的平台,或者是不是这样。
看到上面所有的if 和手势了吗?它们翻译成:
tl;博士 。也许吧。这取决于很多因素。为什么不试试看看呢?不管网上怎么说,这是唯一确定的方法。
- 如何在C++中从字符串中分割字符
- 处理小于cpu数据总线的数据类型.(c++转换为机器代码)
- C++映射分割错误(核心转储)
- C++为线程工作动态地分割例程
- 在模拟器中使用并集来模拟CPU寄存器有多合适
- 由cin中的字符串中未捕获空白引起的分割错误
- 编写一个函数以使用 n 百分比的 CPU 使用率
- 删除映射和分割错误中的一个过去结束元素
- 如何禁用 CPU 的无序执行
- 在指向函数中读取变量时出现分割错误
- CPU 瓶颈;处理具有许多非静态对象的 3D 场景渲染的简单方法
- 在链表中的第 n 位插入显示分割错误
- 较高值 n 的分割错误(例如 n=999997)
- 分别测量每个线程上花费的 CPU 时间(C++)
- 什么时候最好在子进程中使用 CPU 或 I/O 密集型代码 [ C++ ]
- 在程序运行时监视 VxWorks 中的任务 CPU 利用率
- 是否可以制作没有内部分割的cgal 3d多多马因网格?
- 尝试通过memcpy复制大尺寸浮点向量时的分割错误
- 分割错误:向量中的擦除功能
- 我应该分割我的异步调用块根据cpu的数量