我正在使用两个函数:i.find_divisor():查找一个数字和ii的所有除数。 findAmicable数字,用于查找C ++中给定限制的友好对。 以下是查找友好对的代码:
void find_pair() {
while (counter < limit) {
int first_num = counter;
{
lock_guard<mutex> guard(myMutex);
counter++;
int sec_num = find_divisor(first_num);
if (sec_num > first_num && first_num == find_divisor(sec_num)) {
pairvector.push_back({ first_num,sec_num });
}
}
}
}
我从main()调用此函数。 counter和pairvector都是全局变量,我从main中打印对。对于限制100000,使用1个线程,我在596毫秒内得到结果,而使用18个线程,则花费了1507毫秒。我是线程概念和锁的新手。如果我不使用锁,我会得到一些重复的值或缺少值;如果使用锁,则多线程所花的时间比单线程要长。谁能帮助我如何通过多线程获得更好的性能。任何帮助表示赞赏。谢谢
答案 0 :(得分:2)
您对所有线程使用mutex
保护,这意味着只有一个线程可以并行通过这些行:
counter++;
int sec_num = find_divisor(first_num);
if (sec_num > first_num && first_num == find_divisor(sec_num)) {
pairvector.push_back({ first_num,sec_num });
}
如果另一个线程要同时传递它们,它将等待直到第一个线程完成。现在,线程必须从操作系统获得命令才能开始运行,并且可以并行运行的最大线程数限制为计算机拥有的内核数。现在,如果内核数量少于线程数量(或者操作系统将多个线程分配给同一个内核),则某些线程将等待一段时间,直到它们获得从操作系统再次运行的许可。
让我们测试一个案例:
操作系统:8核。
第一个线程获得许可并进入受保护的行。
第二个开始运行并等待,直到第一个线程将从受保护的行中退出。
其余所有问题都停留在第二个问题的情况下,但是现在,其中一些工作在与第一个问题相同的核心上。操作系统现在将第一个线程发送到等待时间,并将让其中一个处于阻塞状态的线程运行权限。但是,第一个仍然留在受保护的行中,因此还没有人可以越过它们。
在这种情况下,所有线程都在等待第一个线程,并且第一个线程正在等待操作系统的许可。一段时间后,操作系统让第一个线程获得了许可,并退出了受保护的行,但是这花费了更长的时间,因为有一个等待时间。.
这是一个过分的案例,这里仅作说明之用
尝试保护尽可能少的行,因此线程中将有更多并行位置。