多线程基准测试

2023-12-25

我进行了大量的数学计算来计算孪生素数 https://en.wikipedia.org/wiki/Twin_prime范围内的数字,我已在线程之间划分任务。

在这里您可以看到执行时间与线程数的关系。

我的问题是关于以下理由的:

  1. 为什么单线程和双线程的性能非常相似?

  2. 为什么使用 5 或 7 线程时执行时间会下降,而使用 6 或 8 线程时执行时间会增加? (我在几次测试中都经历过这一点。)

  3. 我用过8核的电脑。我可以声称 2×n (where n是核心数)根据经验,线程数是一个很好的数量吗?

  4. 如果我使用 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;
}

考虑一下您的程序将在以下时间完成:last线程已完成对其数字范围的检查。也许某些线程比其他线程更快?

需要多久is_prime()怎样判断偶数是素数?它将在第一次迭代时找到它。查找奇数的素数将至少需要两次迭代,如果 a 是素数,则可能需要最多 sqrt(a) 次迭代。is_prime()当给它一个大素数时,它会比给一个偶数慢得多!

在两个线程的情况下,一个线程将检查 100000000、100000002、100000004 等的素数,而另一个线程将检查 100000001、100000003、100000005 等。一个线程检查所有偶数,而另一个线程检查所有奇数(包括所有那些慢素数!)。

把你的线索打印出来("Thread at %ld done", l1)当它们完成时,我认为您会发现某些线程比其他线程快得多,这是由于您在线程之间划分域的方式所致。偶数线程会将所有偶数值赋予同一线程,导致分区特别差,这就是偶数线程数比奇数线程慢的原因。

这将成为一部很棒的XKCD风格的漫画。 “我们需要检查所有这些数字来找到素数!用手!” “好吧,我会检查evens,你会赔率。”

这里真正的问题是,像您所做的那样的固定域分解要求每个分区花费相同的时间才能达到最佳状态。

解决这个问题的方法是动态进行分区。常用的模式涉及以块的形式请求工作的工作线程池。如果该块与线程将完成的总工作相比较小,则所有线程将在相似的时间内完成其工作。

对于您的问题,您可能有一个互斥锁保护的全局数据集start_number, stop_number, total_twins。每个线程都会保存start_number在将其全局值增加之前chunk_size。然后它搜索范围[saved_start_number, saved_start_number+chunk_size),将发现的双胞胎数量添加到全球total_twins完成后。工作线程继续执行此操作,直到start_number >= stop_number。对全局变量的访问使用互斥体进行保护。人们必须调整块大小,以限制因获取块的成本和互斥体争用而导致的低效率,以及由于空闲工作线程没有更多块可分配而另一个线程仍在处理其最后一个块而导致的低效率。如果您使用原子增量来请求块,则块大小可能会小到单个值,但如果在分布式计算系统中需要网络请求,则块大小将需要大得多。这就是它如何工作的概述。

顺便说一句,你的is_prime()测试很幼稚而且非常慢。如果一个数不能被2整除,它能被4整除吗?一个人可以做得更好!

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

多线程基准测试 的相关文章

  • c中的奇异值分解简单代码

    我正在寻找 C 语言的奇异值分解 SVD 代码 你能帮我吗 我找到了很多来源 但我无法运行它们 我正在寻找一个为我提供 S V 和 U 3 个矩阵的 SVD 代码版本 您可以使用数字食谱代码svdcmp c 参考 http tumic wz
  • 委托给子组件的模式

    在我正在工作的产品中 非常基本的场景之一是类的序列化 通常 要序列化的类会在其子组件上调用序列化 例如如果有一个类 s t 班级 A B C D 那么A Pack会调用pack B C D 上的函数 由于有很多这样的类 因此必须一遍又一遍地
  • 良好的类似 STL 的 C 库 [关闭]

    Closed 这个问题不符合堆栈溢出指南 help closed questions 目前不接受答案 对于具有向量 双端队列 堆栈 哈希图 树形图 集合等数据结构的 C 语言来说 有哪些好的库 请使用纯 C 并且与平台无关 The Glib
  • WPF:Prism 对于小型应用程序来说是不是太过分了?

    如果我不将我的应用程序分成不同的模块 否则我会认为 Prism 确实是可行的方法 我应该使用 Prism 吗 我知道 Prism 提供了一个方便的实现ICommand 我可以自己在一页代码中完成 并为我们提供IEventAggregator
  • 将双精度数转换为十六进制 - 代码审查

    我有以下代码 它采用双精度值并将其转换为十六进制表示形式 反之亦然 我想知道它是否存在任何潜在的问题 我是否忽略了某些事情 double hex to double2 string hexString unsigned char byte
  • STL Map 或 HashMap 线程安全吗?

    我可以在多线程程序中使用映射或哈希图而不需要锁吗 即它们是线程安全的吗 我想同时在地图中添加和删除 那里似乎有很多相互矛盾的信息 顺便说一下 我在Ubuntu 10 04下使用的是GCC自带的STL库 编辑 就像互联网的其他部分一样 我似乎
  • 英特尔 SSE:为什么 `_mm_extract_ps` 返回 `int` 而不是 `float`?

    为什么 mm extract ps返回一个int代替float 读单的正确方法是什么float来自 C 中的 XMM 寄存器 或者更确切地说 另一种询问方式是 其相反的是什么 mm set ps操作说明 所有答案似乎都没有真正回答问题 wh
  • ASP.net C#,采用不同参数类型的同名方法[重复]

    这个问题在这里已经有答案了 可能的重复 可以在 ASP Net MVC 中重载控制器方法吗 https stackoverflow com questions 436866 can you overload controller metho
  • 从文件夹中删除文件的单元测试方法

    我们有一个方法 它将文件夹名称和天数作为参数 public void Delete string folder int days var files Directory GetFiles folder foreach var file in
  • C# 返回一个数的倍数和余数?

    我想找到给定数字的 3 的所有倍数 并找到余数 例如 给定数字 10 3 的倍数 3 6 9 余数 1 给定数字 11 3 的倍数 3 6 9 余数 2 到目前为止我的算法 但不是代码 是这样的 检查 X 是否是 3 的倍数 是 返回倍数
  • 如何以编程方式对 WebBrowser 控件安全警报回答“是”

    我正在使用 WebBrowser 控件以编程方式访问单个网站 但每当我登录时 我都会收到此证书安全警报 由于我信任该网站 并且我还需要以编程方式自动登录 因此此对话框会妨碍我 我搜索了解决方案并发现一个和我类似的问题 https stack
  • 为什么不继承 std::allocator

    我创建了自己的分配器 如下所示 template
  • EF4如何在多对多关系中公开联接表

    假设我有以下表格 Essence EssenceSet 和 Essence2EssenceSet 其中 Essence2EssenceSet 仅保存前 2 个表的 ID 以形成 M M 关系 在 EF 中 由于 Essence2Essenc
  • 不能从模板 C++ 类继承[重复]

    这个问题在这里已经有答案了 我不知道这里出了什么问题 也许有人可以帮助我 我想继承我的新班级MyDictionary来自模板抽象类dictionary 我有这样的代码 字典 h ifndef UNTITLED CPP DICTIONARY
  • 为什么 -1 >> 1 和 0xFFFFFFFF >> 1 会产生不同的结果?

    我正在尝试做一个测试来判断我的电脑是否通过右移十六进制执行算术右移或逻辑右移FFFFFFFF by 1 我知道一个整数 1读作FFFFFFFF十六进制 因为它是二进制补码1 右移 1 by 1结果是FFFFFFFF并显示 PC 执行算术右移
  • 组合 lambda 表达式以检索嵌套值

    我正在尝试创建表达式来访问嵌套结构中的字段或属性 我设法为平面对象上的字段和属性创建 getter 和 setter 作为 lambda 表达式 它的工作原理如下 Delegate getter getGetterExpression ob
  • 如何正确初始化“min”变量?

    我的代码中有一个小问题 用于从一系列数字中查找最小值 当我初始化时min 0 最小值结果为0 但是当我不初始化时min 答案是正确的 为什么会出现这种情况 Xcode 告诉我应该初始化min多变的 int a 20 0 int max 0
  • 如何访问 OpenSSL 的 EVP_PKEY 结构中的原始 ECDH 公钥、私钥和参数?

    我正在使用 OpenSSL 的 c 库生成椭圆曲线 Diffie Hellman ECDH 密钥对 遵循第一个代码示例here http wiki openssl org index php Elliptic Curve Diffie He
  • 条件运算符 + 向上转换 + const 引用

    灵感来自这个问题 https stackoverflow com questions 23049166 我尝试了以下代码 struct A virtual void doit const 0 struct B public A virtua
  • 为什么 C# Array.BinarySearch 这么快?

    我已经实施了一个很简单用于在整数数组中查找整数的 C 中的 binarySearch 实现 二分查找 static int binarySearch int arr int i int low 0 high arr Length 1 mid

随机推荐

  • 集中回滚-用于使用@transactional

    是否可以告诉Spring回滚异常MyException也RuntimeException使用时在 XML 配置中 transactional 我知道可以在注释中设置回滚 但如果我有很多服务都设置相同的异常 那么这似乎是多余的 我看到人们建议
  • JUnit 5:指定嵌套测试的执行顺序

    是否可以以固定的执行顺序在其他一些测试之间执行多个嵌套测试 E g TestInstance Lifecycle PER CLASS TestMethodOrder OrderAnnotation class class MyTest pr
  • POSIXct 日期转换错误[重复]

    这个问题在这里已经有答案了 将一组字符格式的日期转换为 POSIXct 对象时 我遇到了以下错误 示例数据 t lt c 3 11 2007 1 30 3 11 2007 2 00 4 11 2007 2 00 str t chr 1 3
  • 如何使用区域设置获取特定国家/地区的货币符号?

    我已经尝试过这段代码 它给了我Country Code对于某些国家而不是currency symbol 我想要货币符号而不是代码 数组 resourcesList 包含所有具有其代码的国家 地区 String m String Array
  • 如何在 Android 应用程序中指定和添加自定义打印机?

    我正在为 Android 创建一个应用程序 所需的应用程序功能的一部分是用户可以选择一个特殊的打印机 我们将其称为传输打印机 它将将要打印的文档传递到在外部服务器上运行的进程 我需要采取哪些步骤才能将自定义打印机添加到 Android 打印
  • 双包含解决方案?

    在 C 中 我遇到了双重包含的问题 文件 stuffcollection h pragma once ifndef STUFFCOLLECTION H define STUFFCOLLECTION H include Stage h cla
  • Tensorflow、try 和 except 不处理异常

    我是张量流的新手 我在这里遇到了一个恼人的问题 我正在制作一个程序 加载使用以下命令拍摄的图像 原始数据 tf WholeFileReader read image name queue 从 tfrecord 文件中读取 然后使用tf im
  • 在同一表达式中调用具有局部副作用的函数两次是否是未定义的行为?

    int f static int i 0 return i int g return f f Does g return 3或者是结果undefined 章节和诗句 http www open std org jtc1 sc22 wg14
  • 属性 insetForeground 已经定义

    更新到新版本后 com android support design 22 2 0 我收到这个错误 属性 insetForeground 已经定义 请记住 我正在使用 romannurikScrimInsetsFrameLayout jav
  • Ruby on Rails,找不到有效的 gem 'rails'

    我安装了 ruby 并更新了 ruby gems 现在我想下载 Rails 3 2 13 我写 gem install Rails v 3 2 13 我需要这个版本 我有这个错误 ERROR Could not find a valid g
  • 为什么我们需要在Python中进行编码和解码?

    编码 解码的用例是什么 我的理解是 编码用于将字符串转换为字节字符串 以便能够在程序中传递非 ascii 数据 而decode就是将这个字节串转换回字符串 有点遵循 示例显示即使未编码 解码 非 ascii 字符也能成功打印 例子 val1
  • 在 PDF 中插入换行符

    我正在使用 PHP 即时生成一些 PDF 文件 我的问题是我需要在将插入 PDF 文件的文本的某些部分插入换行符 就像是 pdf gt InsertText Line one n nLine two 所以它打印 Line one Line
  • Visual Studio 2015 非常慢

    我刚安装完 整个IDE速度超级慢 看起来它正在后台进行某种繁重的 CPU 调用 整个 IDE 几乎冻结并在大约 2 3 秒内变得无响应 我在使用 Visual Studio 2013 Ultimate 时没有遇到此问题 我正在运行 Visu
  • 添加变量导致的段错误

    诚然 我是一个纯 C 新手 但这让我难住了 我正在研究链表实现以进行练习 并且通过简单地将变量添加到 split node 函数中 我遇到了段错误 include
  • 比较两个表的值并列出不同的行

    这个问题与这个问题 https stackoverflow com questions 4602083 sql compare data from two tables 4604221 comment 7562192 但只是略有不同 我有
  • 如何像 jQuery 那样实现链接模式? [复制]

    这个问题在这里已经有答案了 如何创建一个像 jQuery 使用的前缀 例如 在 jQuery 中我可以使用 footer css display none 我想启用类似的语法 如下所示 google footer chrome displa
  • Java Robot createScreenCapture 性能

    我需要抓取一系列屏幕截图并将它们连接成一部电影 我正在尝试使用 java Robot 类来捕获屏幕 但 createScreenCapture 方法在我的机器上花费了超过 1 秒的时间 我什至连 1 fps 都达不到 有办法加快速度吗 或者
  • 如何覆盖android home按钮

    我一直在搜索 Android 文档和 stackoverflow 我正在阅读的大多数答案都说您无法禁用或覆盖 Android 主页按钮 尝试过 不起作用 https stackoverflow com questions 6507063 h
  • Common LISP:将(未知)struct 对象转换为 plist?

    defstruct mydate constructor make mydate year month day year 1970 month 1 day 1 defvar date1 make mydate 1992 1 1 问题更普遍
  • 多线程基准测试

    我进行了大量的数学计算来计算孪生素数 https en wikipedia org wiki Twin prime范围内的数字 我已在线程之间划分任务 在这里您可以看到执行时间与线程数的关系 我的问题是关于以下理由的 为什么单线程和双线程的