- c - 在位数组中找到第一个零
- linux - Unix 显示有关匹配两种模式之一的文件的信息
- 正则表达式替换多个文件
- linux - 隐藏来自 xtrace 的命令
我进行了大量的数学计算来计算 twin prime 的数量。一个范围内的数字,我在线程之间分配了任务。
在这里您可以看到执行时间与线程数的关系。
我的问题是关于理由:
为什么单线程和双线程的性能非常相似?
为什么使用 5 或 7 线程时执行时间会下降,而使用 6 或 8 线程时执行时间会增加? (我在几次测试中都经历过。)
我用过 8 核电脑。根据经验,我可以声称 2×n(其中 n 是核心数)是一个很好的线程数吗?
如果我使用 RAM 使用率较高的代码,我会期望配置文件中出现类似的趋势,还是会随着线程数量的增加而发生显着变化?
这是代码的主要部分,只是为了说明它没有使用太多 RAM。
bool is_prime(long a)
{
if(a<2l)
return false;
if(a==2l)
return true;
for(long i=2;i*i<=a;i++)
if(a%i==0)
return false;
return true;
}
uint twin_range(long l1,long l2,int processDiv)
{
uint count=0;
for(long l=l1;l<=l2;l+=long(processDiv))
if(is_prime(l) && is_prime(l+2))
{
count++;
}
return count;
}
规范:
$ lsb_release -a
Distributor ID: Ubuntu
Description: Ubuntu 16.04.1 LTS
Release: 16.04
Codename: xenial
$ lscpu
Architecture: x86_64
CPU op-mode(s): 32-bit, 64-bit
Byte Order: Little Endian
CPU(s): 8
On-line CPU(s) list: 0-7
Thread(s) per core: 2
Core(s) per socket: 4
Socket(s): 1
NUMA node(s): 1
Vendor ID: GenuineIntel
CPU family: 6
Model: 94
Model name: Intel(R) Core(TM) i7-6700 CPU @ 3.40GHz
Stepping: 3
CPU MHz: 799.929
CPU max MHz: 4000.0000
CPU min MHz: 800.0000
BogoMIPS: 6815.87
Virtualisation: VT-x
L1d cache: 32K
L1i cache: 32K
L2 cache: 256K
L3 cache: 8192K
NUMA node0 CPU(s): 0-7
Flags: fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush dts acpi mmx fxsr sse sse2 ss ht tm pbe syscall nx pdpe1gb rdtscp lm constant_tsc art arch_perfmon pebs bts rep_good nopl xtopology nonstop_tsc aperfmperf eagerfpu pni pclmulqdq dtes64 monitor ds_cpl vmx smx est tm2 ssse3 sdbg fma cx16 xtpr pdcm pcid sse4_1 sse4_2 x2apic movbe popcnt tsc_deadline_timer aes xsave avx f16c rdrand lahf_lm abm 3dnowprefetch intel_pt tpr_shadow vnmi flexpriority ept vpid fsgsbase tsc_adjust bmi1 hle avx2 smep bmi2 erms invpcid rtm mpx rdseed adx smap clflushopt xsaveopt xsavec xgetbv1 dtherm ida arat pln pts hwp hwp_notify hwp_act_window hwp_epp
更新(接受答案后)
新配置文件:
改进后的代码如下。现在,工作负载被公平分配。
bool is_prime(long a)
{
if(a<2l)
return false;
if(a==2l)
return true;
for(long i=2;i*i<=a;i++)
if(a%i==0)
return false;
return true;
}
void twin_range(long n_start,long n_stop,int index,int processDiv)
{
// l1+(0,1,...,999)+0*1000
// l1+(0,1,...,999)+1*1000
// l1+(0,1,...,999)+2*1000
// ...
count=0;
const long chunks=1000;
long r_begin=0,k=0;
for(long i=0;r_begin<=n_stop;i++)
{
r_begin=n_start+(i*processDiv+index)*chunks;
for(k=r_begin;(k<r_begin+chunks) && (k<=n_stop);k++)
{
if(is_prime(k) && is_prime(k+2))
{
count++;
}
}
}
std::cout
<<"Thread "<<index<<" finished."
<<std::endl<<std::flush;
return count;
}
最佳答案
假设您的程序将在最后一个 线程完成检查其数字范围时结束。也许有些线程比其他线程快?
is_prime()
需要多长时间才能确定一个偶数是质数?它会在第一次迭代时找到它。寻找奇数的素数至少需要两次迭代,如果 a 是素数,则可能需要最多 sqrt(a) 次迭代。 is_prime()
当它被赋予一个比偶数大的素数时会慢得多!
在您的双线程情况下,一个线程将检查 100000000、100000002、100000004 等的素数,而另一个线程将检查 100000001、100000003、100000005 等的素数。一个线程检查所有偶数,而另一个线程检查所有奇数(包括所有那些慢素数!)。
让你的线程在它们完成时打印出 ("Thread at %ld done", l1)
,我想你会发现一些线程比其他线程快得多,因为方式您正在划分线程之间的域。偶数个线程会将所有偶数值赋给同一个线程,导致分区特别差,这就是为什么偶数线程比奇数慢。
这将成为一部很棒的 XKCD 式漫画。 “我们需要检查所有这些数字以找到质数!手工!” “好吧,我来查偶数,你来算数。”
这里您真正的问题是像您所做的固定域分解要求每个分区花费相同的时间才能达到最佳。
解决这个问题的方法是动态地做分区。一种常用的模式涉及请求分块工作的工作线程池。如果与线程将完成的总工作相比 block 较小,则所有线程将在相似的时间内完成工作。
对于您的问题,您可以拥有一个互斥锁保护的全局数据集 start_number, stop_number, total_twins
。每个线程在将其全局值增加 chunk_size
之前将保存 start_number
。然后搜索范围 [saved_start_number, saved_start_number+chunk_size)
,完成后将找到的双胞胎数量添加到全局 total_twins
。工作线程一直这样做,直到 start_number >= stop_number
。对全局变量的访问使用互斥锁进行保护。必须调整 block 大小以限制因获取 block 的成本和互斥体上的争用而导致的低效率与空闲工作线程没有更多 block 可分配而另一个线程仍在其最后一个 block 上工作的低效率。如果您使用原子增量来请求 block ,那么 block 大小可能会小到单个值,但如果在分布式计算系统中需要网络请求,那么 block 大小将需要更大。这是其工作原理的概述。
顺便说一句,您的 is_prime()
测试很幼稚而且非常慢。如果一个数不能被 2 整除,它能被 4 整除吗?可以做得更好!
关于c++ - 多线程基准,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41388602/
我想创建一个 Python 基准测试列表。现在我只找到了 this 中的标准基准测试问题和一些来自 Computer Language Benchmarks Game . Python 还有其他基准测
我正在使用 apache 提供的基准文件 TestDFSIO 测试我的 hadoop 配置。我正在根据本教程(资源 1)运行它: http://www.michael-noll.com/blog/20
我刚刚安装了 Ruby 企业版,想对我的系统 Ruby 运行一些基准测试。是否有我应该实现的规范基准测试? 最佳答案 最有趣最深入Ruby benchmarks Antonio Cangiano 的系
我已经生成了基准,用于比较使用 ffmpeg 工具缩小视频文件 (mp4) 的两种方法。 基准以这种格式记录: x.mp4 Output_Resolution : 360p Method : A re
我正在使用 codeigniter 制作一个网站。 如果用户在他的评论中写入 {memory_usage} 2.75MB 将显示给他。它不会给 codeigniter 编写的代码带来安全漏洞吗?有什么
我正在尝试对 XSLT 的两个版本进行基准测试。目前我使用 Visual Studio 进行调试,因为从 .NET 组件调用的 xml 转换。 VS 2010 是我用于开发的 IDE。 我得到的唯一线
我想知道如何测量每个节点的内存带宽(流基准)。我的这个程序仅在一个节点上进行测量,进程和线程的数量如下: MPI_Comm_size(MPI_COMM_WORLD, &numranks); MPI_C
我正在关注 performance test Dapper 社区创建的。 目前,我在运行测试 10000 次后得到以下信息: EF 5 = 21595 毫秒 ADO.NET = 52183 毫秒 小巧
为了测量 CPU 的峰值 FLOPS 性能,我编写了一个小的 C++ 程序。但是测量结果给我的结果比我的 CPU 的理论峰值 FLOPS 大。怎么了? 这是我写的代码: #include #incl
有没有办法在 JUnit 测试套件中放置简单的开始/停止计时? 当我创建一个测试套件类时,它看起来像这样,我可以运行它。但是我怎么能在这里放一个简单的长开始时间变量来显示所有测试运行了多长时间? pu
我想测试MySQL数据库的InnoDB和MyRock引擎之间的高强度写入。为此,我使用 sysbench 进行基准测试。我的要求是: 多线程并发写入同一张表。 支持批量插入(每次插入事务都会插入大量记
我正在尝试构建一个 Nodejs Web 应用程序。当我添加更多代码时,最好有一种方法来测试此类更改对性能的影响,如果可能的话,以及我的应用程序在哪些方面花费最多时间。我目前正在使用 mocha 作为
我希望编写一个简单的每秒帧数动画基准 Javascript 实用程序。 FPS 在这里可能是一个模糊的术语,但理想情况下,它可以让我更准确地比较和衡量不同动画 (CSS3/canvas/webgl)
我是 Python 新手。这是我的第一种解释语言。到目前为止,我曾经学习过Java。因此,当 Java 程序第一次运行时,它的执行速度比下一次要慢。reasi 正在缓存。 import time de
我在 Ubuntu 虚拟机中使用 Apache 2.4.2。我用它来加载测试,向某些 HTTPS url 发送请求。失败请求数为零。但是我的请求都无法真正处理(已经在数据库中查找)。使用相同的 url
(我不确定这是否应该在 https://softwareengineering.stackexchange.com/ 上,如果您认为是,请评论) 我即将为我的学士论文创建 WebGL 实现的基准。我不
编辑: Clojure 基准测试已达到 the Benchmarks Game 。 我已经制作了这个问题社区 wiki 并邀请其他人保持更新。 有人知道 Clojure 的性能基准吗? 我自己做了一些
关注 this benchmark BSON 需要更多的磁盘空间和时间来创建、序列化、反序列化和遍历所有元素。 BSON 的一大优势是,它的遍历速度要快得多。那么这个基准有什么问题呢? 最佳答案 你的
我正在 NextFlow 上执行分散-聚集操作。 它看起来像下面这样: reads = PATH+"test_1.fq" outdir = "results" split_read_ch = chan
我无法让apache benchmark与我的网站配合使用。每当我发出此命令时 ab https://example.com/ 我会得到这个输出错误: This is ApacheBench, Ver
我是一名优秀的程序员,十分优秀!