C++ - 使用 std::async 时显示进度条
C++ - display progress bar when using std::async
所以我正在做一个光线追踪器,为了减少渲染时间,我使用std::async独立进行像素计算。
我使用了 this 教程,一切都很好,而且我确实能够节省大约 70% 的渲染时间。
不过,有些场景需要一段时间才能渲染,我想显示某种进度条。由于我是异步基础设施的新手,所以我不太确定该怎么做。我想要某种机制来仅打印 'main'、调用'、线程的进度。
这里是渲染循环 - 注意进度条的注释行 - 显然不应该放在那里:
Image *image = new Image(width, height);
size_t max = width * height;
size_t cores = std::thread::hardware_concurrency();
volatile atomic<size_t> count(0);
vector<future<void>> future_vector;
while (cores--)
{
future_vector.push_back(
std::async(launch::async, [=, &camera, &scene, &count]()
{
while (true)
{
std::size_t index = count++;
if (index >= max)
break;
GLuint i = index % width;
GLuint j = index / width;
Ray ray = camera.generateRay(i + .5, j - .5);
vec3 color = recursiveRayTrace(scene, ray, maxDepth);
image->setPixel(i, j, color);
// THIS IS BAD
//std::cout << "Progress: [ "<< setprecision(1) << fixed << (count / (GLfloat)max) * 100.0 << "% ] \r";
//std::cout.flush();
}
}));
}
for (auto& e : future_vector) {
e.get();
}
return image;
更新:
所以我按照一些答案的建议做了——这里是结果——供未来的读者参考。
当异步渲染时,我对一些场景的基准测试是 15 秒(我故意采取了一些速度)。
当我使用 mutex 时,时间减慢到 26 秒。 (在单线程上仍然优于 1.32)。
我还积极等待其中一个工作线程,并每隔 100 英里左右不断更新进度 - 渲染时间为 16 秒。所以我对这个结果非常满意,因为印刷几乎没有减慢这个过程。
谢谢,
阿隆
似乎你在使用 std::cout
时需要锁定,否则异步任务会产生混乱的输出(它们都试图同时在控制台上打印)。
但是,我建议您使用 GDIplus(似乎您正在代码中使用)来打印文本,而不是在控制台上显示文本 window,这很丑陋。
Image *image = new Image(width, height);
size_t max = width * height;
size_t cores = std::thread::hardware_concurrency();
volatile atomic<size_t> count(0);
vector<future<void>> future_vector;
mutex cout_lock;
while (cores--)
{
future_vector.push_back(
std::async(launch::async, [=, &camera, &scene, &count]()
{
while (true)
{
std::size_t index = count++;
if (index >= max)
break;
GLuint i = index % width;
GLuint j = index / width;
Ray ray = camera.generateRay(i + .5, j - .5);
vec3 color = recursiveRayTrace(scene, ray, maxDepth);
image->setPixel(i, j, color);
{ //lock variable scope
lock_guard<mutex> lock(cout_lock)
std::cout << "Progress: [ "<< setprecision(1) << fixed << (count / (GLfloat)max) * 100.0 << "% ] \r";
std::cout.flush();
}
}
}));
}
for (auto& e : future_vector) {
e.get();
}
return image;
所以我正在做一个光线追踪器,为了减少渲染时间,我使用std::async独立进行像素计算。 我使用了 this 教程,一切都很好,而且我确实能够节省大约 70% 的渲染时间。
不过,有些场景需要一段时间才能渲染,我想显示某种进度条。由于我是异步基础设施的新手,所以我不太确定该怎么做。我想要某种机制来仅打印 'main'、调用'、线程的进度。
这里是渲染循环 - 注意进度条的注释行 - 显然不应该放在那里:
Image *image = new Image(width, height);
size_t max = width * height;
size_t cores = std::thread::hardware_concurrency();
volatile atomic<size_t> count(0);
vector<future<void>> future_vector;
while (cores--)
{
future_vector.push_back(
std::async(launch::async, [=, &camera, &scene, &count]()
{
while (true)
{
std::size_t index = count++;
if (index >= max)
break;
GLuint i = index % width;
GLuint j = index / width;
Ray ray = camera.generateRay(i + .5, j - .5);
vec3 color = recursiveRayTrace(scene, ray, maxDepth);
image->setPixel(i, j, color);
// THIS IS BAD
//std::cout << "Progress: [ "<< setprecision(1) << fixed << (count / (GLfloat)max) * 100.0 << "% ] \r";
//std::cout.flush();
}
}));
}
for (auto& e : future_vector) {
e.get();
}
return image;
更新: 所以我按照一些答案的建议做了——这里是结果——供未来的读者参考。 当异步渲染时,我对一些场景的基准测试是 15 秒(我故意采取了一些速度)。 当我使用 mutex 时,时间减慢到 26 秒。 (在单线程上仍然优于 1.32)。 我还积极等待其中一个工作线程,并每隔 100 英里左右不断更新进度 - 渲染时间为 16 秒。所以我对这个结果非常满意,因为印刷几乎没有减慢这个过程。
谢谢, 阿隆
似乎你在使用 std::cout
时需要锁定,否则异步任务会产生混乱的输出(它们都试图同时在控制台上打印)。
但是,我建议您使用 GDIplus(似乎您正在代码中使用)来打印文本,而不是在控制台上显示文本 window,这很丑陋。
Image *image = new Image(width, height);
size_t max = width * height;
size_t cores = std::thread::hardware_concurrency();
volatile atomic<size_t> count(0);
vector<future<void>> future_vector;
mutex cout_lock;
while (cores--)
{
future_vector.push_back(
std::async(launch::async, [=, &camera, &scene, &count]()
{
while (true)
{
std::size_t index = count++;
if (index >= max)
break;
GLuint i = index % width;
GLuint j = index / width;
Ray ray = camera.generateRay(i + .5, j - .5);
vec3 color = recursiveRayTrace(scene, ray, maxDepth);
image->setPixel(i, j, color);
{ //lock variable scope
lock_guard<mutex> lock(cout_lock)
std::cout << "Progress: [ "<< setprecision(1) << fixed << (count / (GLfloat)max) * 100.0 << "% ] \r";
std::cout.flush();
}
}
}));
}
for (auto& e : future_vector) {
e.get();
}
return image;