当前位置: 首页 > article >正文

(done) openMP学习 (Day13: 线程私有数据和如何支持库(Pi again),蒙特卡洛计算 Pi,线性同余法)

url: https://dazuozcy.github.io/posts/introdution-to-openmp-intel/#23-%E5%8F%AF%E6%80%95%E7%9A%84%E4%B8%9C%E8%A5%BF%E5%86%85%E5%AD%98%E6%A8%A1%E5%9E%8Batomicsflushpairwise%E5%90%8C%E6%AD%A5%20

视频:https://www.bilibili.com/video/BV1SW411s7ST?spm_id_from=333.788.videopod.episodes&vd_source=7a1a0bc74158c6993c7355c5490fc600&p=26


先来回顾 threadprivate

threadprivate: makes global data private to a thread.

例子:

int counter = 0;
#pragma omp threadprivate(counter) //每个线程都有一个counter变量,并且被初始化为0

int increment_counter()
{
    counter++;
    return (counter);
}

一个例子:蒙特卡洛法计算pi值

#include <random>

static long num_trails = 10000;

void calc_pi_montacalo()
{
    long i;
    long Ncircle = 0;
    double pi, x, y;
    double r = 1.0;

    std::random_device rd;
    std::mt19937 rng(rd());
    std::uniform_real_distribution<> dist(-1.0, 1.0);
    
    #pragma omp parallel for private(x, y) reduction(+:Ncircle)
    for(i = 0; i < num_trails; i++) {
        x = dist(rng);
        y = dist(rng);
        if ((x * x + y * y) <= r * r) {
            Ncircle++;
        }
    }

    pi = 4.0 * ((double)Ncircle / (double)num_trails);
    printf("\n%d trails, pi is %f\n", num_trails, pi);
}

蒙特卡洛算法中要使用随机数生成器。这里出现了一个问题:随机数生成器也许不支持并行,从而导致上述代码无法并行。


线性同余法随机数生成器

在这里插入图片描述

源码:

/* simple single thread version */
static long MULTIPLIER = 1366;
static long ADDEND = 150889;
static long PMOD = 714025;
long random_last = 0;

double random()
{
    long random_next;
    random_next = (MULTIPLIER* random_last + ADDEND) % PMOD;
    random_last = random_next;

    return ((double)random_next / (double)PMOD);
}

经过测试:并行时,同样参数生成的伪随机数并不同
在这里插入图片描述

原因是,上述代码中实际上存在数据竞争:

/* simple single thread version */
static long MULTIPLIER = 1366;
static long ADDEND = 150889;
static long PMOD = 714025;
long random_last = 0;

double random()
{
    long random_next;
    random_next = (MULTIPLIER* random_last + ADDEND) % PMOD;
    random_last = random_next;

    return ((double)random_next / (double)PMOD);
}

比如全局变量 random_last

一个合适的修复方式是对 random_last 做私有化处理:
在这里插入图片描述

现在 LCG方法 已经实现线程安全了,但是可以看到它的分布和单线程有差别。
在这里插入图片描述

会产生更高的 error 的原因是:想象我们是在一串伪随机数上随机选一段连续的数字作为随机数。那么在并行条件下,我们选取多段连续数字,这些多段连续数字可能会 overlap。这就破坏了我们随机数的统计质量。
在这里插入图片描述

使用蛙跳方法修改随机数生成函数可以解决上述问题:
在这里插入图片描述

使用上述方法,多线程的随机数和单线程一摸一样。
在这里插入图片描述



http://www.kler.cn/a/539284.html

相关文章:

  • 数组与指针1
  • 没用的文章又➕1
  • 【键盘识别】实例分割
  • TAPEX:通过神经SQL执行器学习的表格预训练
  • 现在中国三大运营商各自使用的哪些band频段
  • 灵巧手技术全景解析:从仿生设计到智能控制
  • [图文]DeepSeek能做对《软件方法》的测试题吗?
  • python基础入门:4.4模块与包管理
  • SqlSugar简单使用之Nuget包封装-Easy.SqlSugar.Core
  • python pyaudio使用调用本地麦克风获取音频
  • Git仓库托管基本使用05——远程仓库操作
  • k8s证书过期怎么更新?
  • Activity相关学习(二)
  • mmap 文件映射
  • 【C编程问题集中营】使用数组指针时容易踩得坑
  • 单片机之基本元器件的工作原理
  • 4.寻找两个正序数组的中位数
  • PAT乙级真题 — 1074 宇宙无敌加法器(java)
  • 降低获客与裂变渠道成本的新策略:融合开源2+1链动模式、AI智能名片与S2B2C商城小程序
  • Linux 创建进程 fork()、vfork() 与进程管理
  • python基础入门:3.5实战:词频统计工具
  • 问卷数据分析|SPSS之分类变量描述性统计
  • 深入浅出:SSL证书的作用与重要性
  • 第二十一章:考研的艰难抉择与放弃入学的转折
  • 基于javaweb的SpringBoot+MyBatis毕业设计选题答辩管理系统(源码+文档+部署讲解)
  • PromptSource安装报错