我有以下代码:
#include
#include
#include
int main()
{
boost::posix_time::ptime start = boost::posix_time::microsec_clock::local_time();
boost::uint64_t sum = 0;
for (int i = 0; i < 1000000000; ++i)
sum += i;
boost::posix_time::ptime end = boost::posix_time::microsec_clock::local_time();
std::cout << end - start << std::endl;
std::cout << sum << std::endl;
}
任务是:重构以下程序以使用两个线程计算总数.由于现在许多处理器都有两个内核,因此应该通过利用线程来减少执行时间.
这是我的解决方案:
#include
#include
#include
#include
boost::uint64_t s1 = 0;
boost::uint64_t s2 = 0;
void sum1()
{
for (int i = 0; i < 500000000; ++i)
s1 += i;
}
void sum2()
{
for (int i = 500000000; i < 1000000000; ++i)
s2 += i;
}
int main()
{
boost::posix_time::ptime start = boost::posix_time::microsec_clock::local_time();
boost::thread t1(sum1);
boost::thread t2(sum2);
t1.join();
t2.join();
boost::posix_time::ptime end = boost::posix_time::microsec_clock::local_time();
std::cout << end - start << std::endl;
std::cout << s1+s2 << std::endl;
}
请查看并回答以下问题:
1.为什么这段代码实际上并没有优化执行时间? :)(我使用英特尔酷睿i5处理器和Win7 64位系统)
2.为什么当我使用一个变量s来存储和而不是s1和s2时,总和变得不正确?
提前致谢.
解决方法:
我会回答你的第二个问题,因为第一个问题还不清楚.当您使用单个全局变量来计算总和时,会出现由操作引起的所谓“数据竞争”
s += i;
不是“原子的”,意味着在汇编程序级别它被翻译成几个指令.如果一个线程正在执行这组指令,那么它可能被另一个执行相同操作的线程中断,并且结果将不一致.
这是因为操作系统在CPU上和从CPU调度线程这一事实,并且无法预测线程如何交错其指令执行.
在这种情况下,经典模式是有两个局部变量收集每个线程的总和,然后在线程完成其工作后将它们一起汇总成一个全局变量.
标签:c,multithreading,concurrency,optimization,boost
来源: https://codeday.me/bug/20190729/1574756.html