下面的代码取自一个用G++编译的示例。多线程比单线程快2倍。
我在Visual Studio2019中执行它,结果恰恰相反:单线程比多线程快2倍。
#include<thread>
#include<iostream>
#include<chrono>
using namespace std;
using ll = long long;
ll odd, even;
void par(const ll ini, const ll fim)
{
for (auto i = ini; i <= fim; i++)
if (!(i & 1))
even += i;
}
void impar(const ll ini, const ll fim)
{
for (auto i = ini; i <= fim; i++)
if (i & 1)
odd += i;
}
int main()
{
const ll start = 0;
const ll end = 190000000;
/* SINGLE THREADED */
auto start_single = chrono::high_resolution_clock::now();
par(start, end);
impar(start, end);
auto end_single = chrono::high_resolution_clock::now();
auto single_duration = chrono::duration_cast<chrono::microseconds>(end_single - start_single).count();
cout << "SINGLE THREADED\nEven sum: " << even << "\nOdd sum: " << odd << "\nTime: " << single_duration << "ms\n\n\n";
/* END OF SINGLE*/
/* MULTI THREADED */
even = odd = 0;
auto start_multi= chrono::high_resolution_clock::now();
thread t(par, start, end);
thread t2(impar, start, end);
t.join();
t2.join();
auto end_multi = chrono::high_resolution_clock::now();
auto multi_duration = chrono::duration_cast<chrono::microseconds>(end_multi - start_multi).count();
cout << "MULTI THREADED\nEven sum: " << even << "\nOdd sum: " << odd << "\nTime: " << multi_duration << "ms\n";
/*END OF MULTI*/
cout << "\n\nIs multi faster than single? => " << boolalpha << (multi_duration < single_duration) << '\n';
}
但是,如果我对我的函数做一个小的修改,如下所示:
void par(const ll ini, const ll fim)
{
ll temp = 0;
for (auto i = ini; i <= fim; i++)
if (!(i & 1))
temp += i;
even = temp;
}
void impar(const ll ini, const ll fim)
{
ll temp = 0;
for (auto i = ini; i <= fim; i++)
if (i & 1)
odd += i;
odd = temp;
}
多线程的性能更好。我想知道是什么导致了这种行为(在实现方面有哪些可能的差异解释了它)。
此外,我还使用www.onlinegdb.com上的gcc进行了编译,结果与我的计算机中的Visual Studio类似。
你是虚假分享的受害者。
odd
和even
紧挨着驻留,从两个线程访问它们会导致L3高速缓存行争用(也称为虚假共享)。
您可以通过将它们分散64个字节来修复它,以确保它们驻留在不同的缓存行中,例如,如下所示:
alignas(64) ll odd, even;
有了这个改变,我在使用2个线程时获得了很好的加速:
SINGLE THREADED
Even sum: 9025000095000000
Odd sum: 9025000000000000
Time: 825954ms
MULTI THREADED
Even sum: 9025000095000000
Odd sum: 9025000000000000
Time: 532420ms
至于G++的性能--它可能是在执行您手动为您做的优化。MSVC在优化全局变量时会更加小心。
我在程序(计时器类)中使用scheduleAtFixedRate方法。它每秒钟运行一次,但有时这种方法会变得非常快(每秒执行3-4次)。 然而,我在网上做了一些研究,发现了这个: 复制自android开发者页面: 对于固定速率执行,任务每次连续运行的开始时间都是计划的,而不考虑上一次运行的时间。如果延迟阻止计时器按时启动任务,则这可能会导致一系列串接运行(一个接一个地启动)。 我需要固定的计时器。
问题内容: 据我了解,使用Java反射API会按顺序减慢代码执行速度。但是后来我看到它在Java Universe中的许多地方都在使用。仅举几例: 注解 春季框架(AOP) 冬眠 MyBatis 这意味着我错过了关于Java反射(又称优化技术)的一些事实。有指针吗? 问题答案: 要点: 因为他们别无选择 。 Java不是动态语言,因此这些框架提供服务的唯一途径是反思。 其次,请注意,在初始化期间,
问题内容: 如何与线程共享全局变量? 我的Python代码示例是: 我不知道如何让两个线程共享一个变量。 问题答案: 您只需要在中声明为global ,这样就无需修改该函数本地的。 在中,您不需要执行任何特殊操作,只要您不尝试修改的值(这将创建一个局部变量以遮盖全局变量;请在需要时使用)>
问题内容: 我一直在使用HTMLUnit。非常适合我的要求。但这似乎非常缓慢。例如:我已经使用HTMLUnit自动化了以下场景 代码: 它运作良好100%。但是需要3分41秒 我想执行缓慢的原因是要验证页面上的每个元素。 我的问题是如何减少HTMLUnit的执行时间?有什么方法可以禁用网页上的验证。 提前致谢! 问题答案: 对于当前的htmlUnit 2.13,设置选项与maxmax提供的设置略有
问题内容: 现在我正在研究如何尽快从网站获取数据。为了获得更快的速度,即时通讯正在考虑使用多线程。这是我用来测试多线程和简单文章之间差异的代码。 如您所见,这是一个非常简单的代码。首先,我将模式设置为“ Simple”,然后我可以得到时间间隔: 50s (也许我的速度有点慢:()。然后我将模式设置为“ Multiple”,然后我得到了时间间隔: 35 。从我可以看到,多线程实际上可以提高速度,但是
消费者是一个spring集成项目,它从消息队列中消费并执行大量处理。目前,它是单线程的,不能与生产者发送消息的速度匹配。因此队列深度不断增加 是否可以使用executor通道在多线程环境中处理此问题并加快使用者进程 如果是,请建议如何实现--为了确保消息的顺序,我需要将相同类型的消息(基于消息的id)分配给executor通道的相同线程。 因此executor通道上的BridgeTo将转发消息