Tho*_*mas 5 c++ multithreading asynchronous
我正在学习 C++ 并且正在制作一个实时光线追踪器。首先我使用 std::thread 来传播工作,但结果证明每帧启动 32 个线程比需要完成的实际工作慢得多。
然后我发现 C++ 也使用线程池通过 std::async() 来处理这个问题:
void trace()
{
constexpr unsigned int thread_count = 32;
std::future<void> tasks[thread_count];
for (auto i = 0u; i < thread_count; i++)
tasks[i] = std::async(std::launch::async, raytrace_task(sample_count, world_), 10, 10);
for (auto i = 0u; i < thread_count; i++)
tasks[i].wait();
}
Run Code Online (Sandbox Code Playgroud)
并且 raytrace_task 为空:
struct raytrace_task
{
// simple ctor omitted for brevity
void operator()(int y_offset, int y_count)
{
}
}
Run Code Online (Sandbox Code Playgroud)
但这与制作自己的线程一样慢。每次调用 trace() 大约需要 30 毫秒!谁能告诉我我做错了什么或如何重用线程?又名:在整个时间内将许多数据处理作业发布到单个重用线程。
谢谢你
感谢所有的评论。我最终结合了Ted Lyngmo 的示例,该示例使用我的所有核心将性能从每帧 80 毫秒提高到 7 毫秒。
任务结构:
#ifdef __cpp_lib_hardware_interference_size
using std::hardware_constructive_interference_size;
using std::hardware_destructive_interference_size;
#else
constexpr std::size_t hardware_constructive_interference_size = 2 * sizeof(std::max_align_t);
constexpr std::size_t hardware_destructive_interference_size = 2 * sizeof(std::max_align_t);
#endif
struct alignas(hardware_destructive_interference_size) raytrace_task
{
// ctor omitted
void operator()()
{
// raytrace one screen-chunk here
}
}
Run Code Online (Sandbox Code Playgroud)
以及每帧触发光线跟踪的代码:
#include <execution>
// ...
void trace()
{
const auto thread_count = std::thread::hardware_concurrency();
// generate render-chunks into multiple raytrace_tasks:
std::vector<raytrace_task> tasks;
for (auto i = 0u; i < thread_count; i++)
{
tasks.push_back(raytrace_task(world_, i, thread_count, camera_, screen_));
}
// run the raytrace_tasks:
std::for_each(std::execution::par, tasks.begin(), tasks.end(), [](auto& task) { task(); });
}
Run Code Online (Sandbox Code Playgroud)
注意:我还必须将 Visual Studio 设置为在 C++17 中编译(项目属性 > C/C++ > 语言)
| 归档时间: |
|
| 查看次数: |
239 次 |
| 最近记录: |