【发布时间】:2021-07-11 23:46:51
【问题描述】:
我有一个带有Mainloop 的简单渲染程序,它在一个线程上以大约 8000 fps 的速度运行(它除了绘制背景之外什么都不做),我想看看另一个线程渲染是否会在不改变当前上下文的情况下扰乱当前上下文(这并不令我惊讶)。我在这里用这个简单的代码实现了这一点,
m_Thread = std::thread(Mainloop);
m_Thread.join();
这里的代码运行速度非常慢,大约 30 FPS。我觉得这很奇怪,我记得在另一个项目中我出于类似的基于性能的原因使用了std::future。于是我用std::future用下面的代码试了一下:
m_Future = std::async(std::launch::async, Mainloop);
m_Future.get();
这仅比单线程性能 (~7900) fps 低一点点。为什么std::thread 比std::future 慢这么多?
编辑:
忽略上面的代码,这里是一个最小的可重现示例,只需将THREAD 切换为0 或1 进行比较:
#include <future>
#include <chrono>
#include <Windows.h>
#include <iostream>
#include <string>
#define THREAD 1
static void Function()
{
}
int main()
{
std::chrono::high_resolution_clock::time_point start = std::chrono::high_resolution_clock::now();
std::chrono::high_resolution_clock::time_point finish = std::chrono::high_resolution_clock::now();
long double difference = 0;
long long unsigned int fps = 0;
#if THREAD
std::thread worker;
#else
std::future<void> worker;
#endif
while (true)
{
//FPS
finish = std::chrono::high_resolution_clock::now();
difference = std::chrono::duration_cast<std::chrono::nanoseconds>(finish - start).count();
difference = difference / 1000000000;
if (difference > 0.1) {
start = std::chrono::high_resolution_clock::now();
std::wstring fpsStr = L"Fps: ";
fpsStr += std::to_wstring(fps);
SetConsoleTitle(fpsStr.c_str());
fps = 0;
}
#if THREAD
worker = std::thread(Function);
worker.join();
#else
worker = std::async(std::launch::async, Function);
worker.get();
#endif
fps += 10;
}
return 0;
}
【问题讨论】:
-
这里的差异似乎是统计噪音和微不足道的。也许慢了一点,但远不及“这么慢”。
-
你的编译器和版本是什么?对于 Windows,可能有
async的后台线程池 -
@SamVarshavchik ??不将未来与单线程进行比较,将 std::thread 与 std::future 进行比较,30 fps -> 7900 fps 非常重要?
-
取决于实现。我有一个应用程序使用异步运行速度比单线程快 5 倍,使用 MSVC 线程运行速度快 3 倍。那是在6核系统上。创建线程有开销,而异步使用开销较少的线程池。但是您还需要在线程中做足够的工作来克服开销。并且您需要优化内存使用,以便线程不会访问彼此的内存。
-
创建
thread并加入它就像告诉某人购买一辆新车并将其开到商店然后出售汽车;而async就像告诉某人打车去商店一样。您可以希望看到为什么线程较慢。出租车公司管理着一支活跃的车队,他们当然不会每次有人叫出租车时都买一辆新车。
标签: c++ multithreading c++11 future stdthread