我想在MFC中使用多线程。我做了一个小实验,看看程序是否以并行方式运行。我写了两个这样的线程函数:
UINT CMFCApplication2Dlg::thread01(LPVOID pParam)
{
clock_t t1, t2;
t1 = clock();
for (int i = 0; i < 300000; i++)
cout << "thread01111111111" << endl;
t2 = clock();
cout << "clock is " << t2 - t1 << endl;
return 0;
}
UINT CMFCApplication2Dlg::thread02(LPVOID pParam)
{
clock_t t1, t2;
t1 = clock();
for (int i = 0; i < 300000; i++)
cout << "thread02222222222" << endl;
t2 = clock();
cout << "clock is " << t2 - t1 << endl;
return 0;
}
并调用它们并输出到控制台窗口:
AllocConsole();
freopen("CONOUT$", "w+t", stdout);
freopen("CONIN$", "r+t", stdin);
printf("Hello World!\n");
CWinThread *pThread01;
CWinThread *pThread02;
pThread01 = AfxBeginThread(thread01, this, 0, 0, 0, NULL);
pThread02 = AfxBeginThread(thread02, this, 0, 0, 0, NULL);
一起运行两个线程时,计数为118020;运行单线程时,计数为60315;当以串行方式将两个循环放在同一个线程中时,我得到102795。
我曾经认为编译器可以优化多线程自动并行执行,但看起来像单核多线程并发。它不会减少运行时间。我使用的CPU有4个核心。我应该怎么做才能在不同的核心并行运行线程以实现高性能?
答案 0 :(得分:3)
两个线程都在尝试同时使用共享资源(std::cout
)。系统必须在一个点上序列化输出,因此大多数时候其中一个线程将等待另一个线程完成写入。这称为同步。当您使用线程进行性能改进时,您希望尽可能减少同步所花费的时间,因为在此期间线程无法完成有用的工作。
尝试通过冗长的计算替换内部循环中的cout
,并且仅在末尾使用cout
来打印最终结果,因此编译器无法优化计算(没有{{1它可以,因为计算没有可观察到的影响。)
此外,cout
缺乏分析的精确度。我建议使用std::chrono::high_resolution_clock
代替,这通常是在Windows平台上使用std::clock
实现的。这是Windows上最好的。
试试这个:
QueryPerformanceCounter()
确保计算不是太简单,因为优化器非常聪明,可能会将您的O(n)算法转换为O(1)。它甚至可以在编译时执行整个计算,并且仅在运行时分配常量。
为避免这种情况,您可以从INT CMFCApplication2Dlg::thread01(LPVOID pParam)
{
using myclock = std::chrono::high_resolution_clock;
auto t1 = myclock::now();
std::int64_t first = 0, second = 1, result = 0;
for( std::int64_t i = 0; i < 10000000; ++i )
{
result = first + second;
first = second;
second = result;
}
auto t2 = myclock::now();
std::chrono::duration<double> td = t2 - t1; // duration in seconds
std::cout << "result is " << result << '\n'
<< "clock is " << std::fixed << std::setprecision( 6 ) << td.count() << " s" << std::endl;
return 0;
}
读取循环迭代次数。虽然在MSVC 2017上测试上述代码时即使完全优化也不需要这样做。
答案 1 :(得分:-1)
阅读并发运行时。它可以帮助你摆脱困境:https://msdn.microsoft.com/en-us/library/dd504870.aspx