OpenMP并行编程计算π值及PSRS排序

《并行计算》 并行计算性能评测 并行模型与并行算法 呜~ 就隔了一段时间没看并行计算,发现作业贼难顶,不得不写篇博客来记录一下复习(预习)的内容。 并行计算性能评测 并行机的一些基本性能指标 对并行计算机的性能关注点还是落在了CPU和存储器上,毕竟CPU和存储器决定了计算机处理问题速度的上限。 在https://www.top500.org/收录了世界上前500台计算能力最强的计算机 可以看到,超算top 5领域美国就居了3个,我国神威·太湖之光排名4,看看神威的详细配置: 这么多核核内存orz… 不过好像处理器的频数并没有那么高,其实也就1.45G. 阅读详情

一. OpenMP简介

OpenMP是一个共享存储并行系统上的应用程序接口。它规范了一系列的编译制导、运行库例程和环境变量。

它提供了C/C++和FORTRAN等的应用编程接口,已经应用到UNIX、Windows NT等多种平台上。

OpenMP使用FORK-JOIN并行执行模型。所有的OpenMP程序开始于一个单独的主线程(Master Thread)。主线程会一直串行地执行,直到遇到第一个并行域(Parallel Region)才开始并行执行。

①FORK:主线程创建一队并行的线程,然后,并行域中的代码在不同的线程队中并行执行;②JOIN:当诸线程在并行域中执行完之后,它们或被同步或被中断,最后只有主线程在执行。

作用域:
编译制导语句的作用域(Scopng)可分为静态范围、孤幼 制导和动态范围。

并行域结构:
一个能被多个线程执行的程序块,它是最基本的OpenMP并行结构,具体格式如下:
# pragma omp parallel [if (scalar_expression) | private (list) | shared (list) | defalut (shared | none) | firstprivate (list) | reduction (operator:list) | copyin (list)] newline

OpenMP的环境变量:
OMP_SCHEDULE:控制for循环任务分配结构的调度
OMP_NUM_THREADS:设置默认线程的个数

OpenMP的库函数
int omp_get_num_threads(void):返回当前使用的线程个数,如果在并行区域外则返回1;
int omp_set_num_threads(int i):设置要使用的线程个数,它可以覆盖OMP_NUM_THREADS;
int omp_get_thread_num(void):返回当前线程号,0代表主线程;
int omp_get_num_procs(void):返回可用的处理核(处理器)个数,对于支持超线程技术的处理器被算作两个处理核。

OpenMP的编译
windows平台 intel C++编译器: 命令 icl /Qopenmp
linux平台 intel C++编译器: 命令 icl -openmp
gcc: 命令 gcc -fopenmp

Visual Studio 对OpenMP的支持:
属性-C/C++-语言-OpenMP支持
1

Linux环境对OpenMP的支持:
在Linux上编译和运行OpenMP程序
编译OpenMP程序: gcc a.c –fopenmp –o a
运行OpenMP程序: ./a

二.利用积分法计算π

在这里简单说明一下求π的积分方法,使用公式arctan(1)=π/4以及(arctan(x))’=1/(1+x^2).
在求解arctan(1)时使用矩形法求解:
求解arctan(1)是取a=0, b=1.
2

1.串行代码:

#include <stdio.h>
static long num_steps = 100000;//越大值越精确
double step;
void main(){
    int i;
    double x, pi, sum = 0.0;
    step = 1.0/(double)num_steps;
    for(i=1;i<= num_steps;i++){
        x = (i-0.5)*step;
        sum=sum+4.0/(1.0+x*x);
    }
    pi=step*sum;
    printf("%lf\n",pi);
}

2.使用并行域并行化的程序:

#include <stdio.h>
#include <omp.h>
static long num_steps = 100000;
double step;
#define NUM_THREADS 2
void main ()
{ 
    int i;
    double x, pi, sum[NUM_THREADS];
    step = 1.0/(double) num_steps;
    omp_set_num_threads(NUM_THREADS);  //设置2线程
 #pragma omp parallel private(i)  //并行域开始,每个线程(0和1)都会执行该代码
{
    double x;
    int id;
    id = omp_get_thread_num();
    for (i=id, sum[id]=0.0;i< num_steps; i=i+NUM_THREADS){
        x = (i+0.5)*step;
        sum[id] += 4.0/(1.0+x*x);
    }
}
    for(i=0, pi=0.0;i<NUM_THREADS;i++)  pi += sum[i] * step;
    printf("%lf\n",pi);
 }  
//共2个线程参加计算,其中线程0进行迭代步0,2,4,...线程1进行迭代步1,3,5,....

3.使用共享任务结构并行化的程序:

#include <stdio.h>
#include <omp.h>
static long num_steps = 100000;
double step;
#define NUM_THREADS 2
void main ()
{ 
    int i;
    double x, pi, sum[NUM_THREADS];
    step = 1.0/(double) num_steps;
    omp_set_num_threads(NUM_THREADS);  //设置2线程
 #pragma omp parallel  //并行域开始,每个线程(0和1)都会执行该代码
{
    double x;
    int id;
    id = omp_get_thread_num();
    sum[id]=0;
#pragma omp for  //未指定chunk,迭代平均分配给各线程(0和1),连续划分
    for (i=0;i< num_steps; i++){
        x = (i+0.5)*step;
        sum[id] += 4.0/(1.0+x*x);
    }
}
    for(i=0, pi=0.0;i<NUM_THREADS;i++)  pi += sum[i] * step;
    printf("%lf\n",pi);
}//共2个线程参加计算,其中线程0进行迭代步0~49999,线程1进行迭代步50000~99999.

4.使用private子句和critical部分并行化的程序:

#include <stdio.h>
#include <omp.h>
static long num_steps = 100000;
double step;
#define NUM_THREADS 2
void main ()
{ 
    int i;
    double pi=0.0;
    double sum=0.0;
    double x=0.0;
    step = 1.0/(double) num_steps;
    omp_set_num_threads(NUM_THREADS);  //设置2线程
#pragma omp parallel private(x,sum,id) //该子句表示x,sum变量对于每个线程是私有的(!!!注意id要设为私有变量)
{
    int id;
    id = omp_get_thread_num();
    for (i=id, sum=0.0;i< num_steps; i=i+NUM_THREADS){
        x = (i+0.5)*step;
        sum += 4.0/(1.0+x*x);
    }
#pragma omp critical  //指定代码段在同一时刻只能由一个线程进行执行
    pi += sum*step;
}
    printf("%lf\n",pi);
}   //共2个线程参加计算,其中线程0进行迭代步0,2,4,...线程1进行迭代步1,3,5,....当被指定为critical的代码段  正在被0线程执行时,1线程的执行也到达该代码段,则它将被阻塞知道0线程退出临界区。

5.使用并行规约的并行程序:

#include <stdio.h>
#include <omp.h>
static long num_steps = 100000;
double step;
#define NUM_THREADS 2
void main ()
{ 
    int i;
    double pi=0.0;
    double sum=0.0;
    double x=0.0;
    step = 1.0/(double) num_steps;
    omp_set_num_threads(NUM_THREADS);  //设置2线程
#pragma omp parallel for reduction(+:sum) private(x) //每个线程保留一份私有拷贝sum,x为线程私有,最后对线程中所以sum进行+规约,并更新sum的全局值
    for(i=1;i<= num_steps; i++){
        x = (i-0.5)*step;
        sum += 4.0/(1.0+x*x);
    }
    pi = sum * step;
    printf("%lf\n",pi);
}   //共2个线程参加计算,其中线程0进行迭代步0~49999,线程1进行迭代步50000~99999.

三.PSRS算法的设计

1.PSRS算法简介
PSRS排序可分为8个部分:
均匀划分: 将n个元素A[1..n]均匀划分成p段,每个pi处理A[(i-1)n/p+1..in/p];
局部排序:pi调用串行排序算法对A[(i-1)n/p+1..in/p]排序;
正则采样:pi从其有序子序列A[(i-1)n/p+1..in/p]中选取p个样本元素;
采样排序:用一台处理器对p2个样本元素进行串行排序;
选择主元:用一台处理器从排好序的样本序列中选取p-1个主元,并
播送给其他pi;
主元划分:pi按主元将有序段A[(i-1)n/p+1..in/p]划分成p段;
全局交换:各处理器将其有序段按段号交换到对应的处理器中;
归并排序:各处理器对接收到的元素进行归并排序。
3

2.PSRS并行算法设计思想

首先确定算法中调用的串行排序为归并排序,总共需要调用3次。
接下来对算法的各个部分进行并行设计,伪代码如下:

定义处理器处理段个数数组变量、划分段的大小、正则采样数p、主元数组、处理器各部分排序的三维数组空间。
设置并行线程后,添加第一个并行域:
\#pragma omp parallel shared(base,array,n,i,pivot,count) private(id)
{
  每个处理器对所在的段进行局部串行归并排序;
  并行域嵌套
  #pragma omp critical
  {
    每个处理器选出p个样本;
      }
  设置路障#pragma omp barrier
  主线程并行域#pragma omp master
  {
        选出num_threads-1个主元
  }
  设置路障#pragma omp barrier
  {
        根据主元对每一个cpu数据进行划分
  }
}
第二个并行域:
#pragma omp parallel shared(pivot_array,count)
{
  向各个线程发送数据,各个线程自己排序;
  打印输出数据;
}
主函数测试数组排序。

3.PSRS排序并行算法实现:

#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<omp.h>

#define num_threads 3

int *L,*R;

//Merge函数合并两个子数组形成单一的已排好序的字数组
//并代替当前的子数组A[p..r] 
void Merge(int *a, int p, int q, int r)
{
    int i,j,k;
    int n1 = q - p + 1;
    int n2 = r - q;
    L = (int*)malloc((n1+1)*sizeof(int));
    R = (int*)malloc((n2+1)*sizeof(int));
    for(i=0; i<n1; i++)
        L[i] = a[p+i];
    L[i] = 65536;
    for(j=0; j<n2; j++)
        R[j] = a[q+j+1];
    R[j] = 65536;
    i=0,j=0;
    for(k=p; k<=r; k++){
        if(L[i]<=R[j]){
            a[k] = L[i];
            i++;
        }
        else{
            a[k] = R[j];
            j++;
        }
    }
} 
//归并排序
void MergeSort(int *a, int p, int r)
{
    if(p<r){
        int q = (p+r)/2;
        MergeSort(a,p,q);
        MergeSort(a,q+1,r);
        Merge(a,p,q,r);
    }
} 

void PSRS(int *array, int n)
{
    int id;
    int i=0;
    int count[num_threads][num_threads] = { 0 };    //每个处理器每段的个数
    int base = n / num_threads;     //划分的每段段数
    int p[num_threads*num_threads]; //正则采样数为p
    int pivot[num_threads-1];       //主元
    int pivot_array[num_threads][num_threads][50]={0};  //处理器数组空间

    omp_set_num_threads(num_threads);
#pragma omp parallel shared(base,array,n,i,p,pivot,count) private(id)
    {
        id = omp_get_thread_num();
        //每个处理器对所在的段进行局部串行归并排序
        MergeSort(array,id*base,(id+1)*base-1);

#pragma omp critical
        //每个处理器选出P个样本,进行正则采样
        for(int k=0; k<num_threads; k++)
            p[i++] = array[(id-1)*base+(k+1)*base/(num_threads+1)];
//设置路障,同步队列中的所有线程
#pragma omp barrier
//主线程对采样的p个样本进行排序
#pragma omp master
        {
            MergeSort(p,0,i-1);
            //选出num_threads-1个主元
            for(int m=0; m<num_threads-1; m++)
                pivot[m] = p[(m+1)*num_threads];
        }
#pragma omp barrier
        //根据主元对每一个cpu数据段进行划分
        for(int k=0; k<base; k++)
        {
            for(int m=0; m<num_threads; m++)
            {
                if(array[id*base+k] < pivot[m])
                {
                    pivot_array[id][m][count[id][m]++] = array[id*base+k];
                    break;
                }
                else if(m == num_threads-1) //最后一段
                {
                    pivot_array[id][m][count[id][m]++] = array[id*base+k];
                }
            }
        }
    }
//向各个线程发送数据,各个线程自己排序
#pragma omp parallel shared(pivot_array,count)
    {
        int id=omp_get_thread_num();
        for(int k=0; k<num_threads; k++)
        {
            if(k!=id)
            {
                memcpy(pivot_array[id][id]+count[id][id],pivot_array[k][id],sizeof(int)*count[k][id]);
                count[id][id] += count[k][id];
            }
        }
        MergeSort(pivot_array[id][id],0,count[id][id]-1);
    }
    i = 0;
    printf("result:\n");
    for(int k=0; k<num_threads; k++)
    {
        for(int m=0; m<count[k][k]; m++)
        {
            printf("%d ",pivot_array[k][k][m]);
        }
        printf("\n");
    }
}

int main()
{
    int array[36] = { 16,2,17,24,33,28,30,1,0,27,9,25, 34,23,19,18,11,7,21,13,8,35,12,29 , 6,3,4,14,22,15,32,10,26,31,20,5 };
    double begin,end,time;
    begin = omp_get_wtime();
    PSRS(array, 36);
/*  MergeSort(list,0,35);
    for(int i=0; i<36; i++)
    {
        printf("%d ",list[i]);
    }*/
    end = omp_get_wtime();
    time = end - begin;
    printf("The running time is %lfs\n",time);
    return 0;
}

4.运行结果:
4
显示排序结果正确,但该PSRS排序带来的额外开销使得所用时间并没有比归并排序算法快,至少在排序规模100以下,归并排序算法占优势。

OpenMP实现计算pi值和PSRS排序并行计算实验 并行计算课程实验代码,c语言写的,在MacOS系统下的openmp的pi值计算和PSRS的实现,注释清晰,且PSRS处理了不整除的情况。懒得编译可使用我提供的run.sh脚本。加上待编译的文件作为参数即可。 立即下载

相关推荐

使用MPI实现的PSRS并行排序算法

使用MPI计算的完整的PSRS(并行排序(parallel sorting by regular sampling))代码。并行计算课实验所用代码。

MPI并行正则采样排序PSRS算法原理及实现

正则采样排序PSRS的MPI算法 算法流程 假设有 ppp 个进程,有 NNN 条数据需要排序。 均匀划分:将 NNN 条数据均匀划分为 ppp 段,每个进程处理一段数据。其中 i&amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;nbsp;(i=0,1,…,p−1)i\ (i=0,1,\dots,p-1)i&amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;nbsp;(i=0,1,…,p−1) 号进程处理 ⌊i×Np⌋\lflo

HenryLiu的博客 8331

BUUCTF--[OGeek2019]babyrop

才学习了基本的ROP流程,到处找题练,不过也没做出来几道题,以这道32位的题作为例题吧。 这道题是BUUCTF上pwn练习题里的[OGeek2019]babyrop。 代码审计 老规矩先checksec一下: 没有canary保护,nx保护开启排除shellcode可能性,FULL RELEO为地址随机化。 观察主函数,先设定了一个闹铃,到时间就会强制退出程序,解除闹铃的方法在上一篇博客中提到过了, 这道题中闹铃函数依然对我们解题起不到什么干扰作用。 主函数的思路大概是:生成一个随机数,把这个随机数作为

N1rvana的博客 6009

并行计算:OpenMP(四)——一些函数操作

OpenMP中提供的函数一般与获取系统信息、上锁相关。

JacksonKim的博客 4175

C#粘包和分包问题及解决方法

一:通过图解法来描述一下分包和粘包,这样客户更清晰直观的了解:  下面对上面的图进行解释:  1.正常情况:如果Socket Client 发送的数据包,在Socket Server端也是一个一个完整接收的,那个就不会出现粘包和分包情况,数据正常读取。  2.粘包情况:Socket Client发送的数据包,在客户端发送和服务器接收的情况下都有可能发送,因为客户端发送的数据都是发送的一个缓冲...

weixin_42033401的博客 7767

使用kmplot在线进行生存分析

欢迎关注”生信修炼手册”!kmplot是一个生存分析的在线工具,最初是设计用来对肝癌中的miRNA进行生存分析,对应的文章发表在scientific reports上,链接如下https...

庐州月光的博客 1万+

openMP的一点使用经验

最近在看多核编程。简单来说,由于现在电脑CPU一般都有两个核,4核与8核的CPU也逐渐走入了寻常百姓家,传统的单线程编程方式难以发挥多核CPU的强大功能,于是多核编程应运而生。按照我的理解,多核编程可以认为是对多线程编程做了一定程度的抽象,提供一些简单的API,使得用户不必花费太多精力来了解多线程的底层知识,从而提高编程效率。这两天关注的多核编程的工具包括openMP和TBB。按照目前网上的讨论,...

weixin_30449453的博客 2184

ADRV9009的学习历程(一)

** AD9361的同胞ADRV9009 ** 终于记录一下了 距离第一次想写博客记录自己学习的点点滴滴,大概已经过去有一年有余。一直都是停留在心有余而力不足的境界。 基本每次做项目遇到问题都会来优快云寻求帮助,这里虽离庙堂较远,但高手云集。每每读来,思绪万千,次次膜拜。 趁这次又学习了一样新物件,就记录一下,望大神看见能赐教一下。 ADRV9009 最近有项目要用到ADRV9009这个芯片。就来学习一下。做过AD9361的都知道,ADI官方会给出这个芯片的参考手册、数据手册和驱动程序。当然我只是见过AD

weixin_42868560的博客 1万+

【openMP并行计算】计算π

Linux环境对OpenMP的支持: 在Linux上编译和运行OpenMP程序 编译OpenMP程序: gcc -fopenmp a.c 运行OpenMP程序: ./a.out 1. 串行计算π #include <stdio.h> #include <omp.h> static long num_steps = 100000000; double step; int ma...

Gilgame的博客 5631

《手把手教你玩转RTOS操作系统》专栏简介

《手把手教你玩转RTOS操作系统》专栏系统讲解实时操作系统开发,以FreeRTOS为主线,结合RT-Thread和Zephyr对比分析。内容涵盖RTOS基础、任务管理、通信机制、中断处理等核心知识,并配套STM32/ESP32平台实战项目。专栏特色在于零基础友好、实战驱动、多系统对比和行业趋势分析,适合嵌入式开发者进阶RTOS开发能力,解决实际项目中的选型与优化问题。通过完整学习路径,读者可掌握构建高可靠性嵌入式系统的关键技能。

MHD0815的博客 531

【微信小程序】微信小程序 manifest.json 配置 ES6 转 ES5 开关:3步让你的代码兼容性更强

ES6(ECMAScript 6)是 JavaScript 的最新标准,引入了许多新的语法和特性,如箭头函数、模板字符串、解构赋值等。然而,不是所有的环境都支持 ES6,特别是旧版本的浏览器和一些特定的运行环境。为了确保代码的兼容性,我们需要将 ES6 代码转换为 ES5 代码。通过本文的详细讲解,相信你已经学会了如何在文件中配置微信小程序的 ES6 转 ES5 开关。这个小小的配置步骤能够显著提高代码的兼容性和稳定性。如果你有任何问题或需要进一步的帮助,欢迎随时留言交流。

java专栏 1361

随机森林算法的加速:OpenMP方法

OpenMP用于编写多线程应用程序的 API。它是一组编译器指令和库例程,使并行编程比使用显式线程更容易它实际上大大简化了用 Fortran 、C/ C++ 编写多线程编程程序。主流编译器(gcc/g++,Visual C++)都支持OpenMP,在Windows和Linux操作系统上都比较容易上手,对原始代码的侵入较少。随机森林由N棵随机树(Randomized Trees)组成,在训练与其他衍生算法中,很多情形下每棵树内的运算是独立的,且与树的顺序无关。

Working hard and Focus 804

【Windows Server 2019】组策略的配置与管理——理论基础

博文介绍了组策略的定义,作用和分类。组策略包括计算机配置和用户配置;组策略又分为为基于本地的组策略和基于AD(活动目录)的域组策略。并说明了不同组策略发生冲突时默认的规则。

VMware, Windows, Linux, Cisco, Container, Kubernetes, Kali 1万+

OpenMP学习笔记2

OpenMP学习笔记2 OpenMP子句的用法 private 子句 firstprivate子句 lastprivate子句 threadprivate子句 shared子句 reduction子句

dearest_____的博客 454

海思3516A移植MT7601U编译过程记录

官方地址:https://www.mediatek.com/products/broadbandWifi/mt7601 tar -xjf DPO_MT7601U_LinuxSTA_3.0.0.4_20130913.tar.bz2 cd DPO_MT7601U_LinuxSTA_3.0.0.4_20130913 1> Makefile替换 PLATFORM = HISI_3516A ifeq ($(PLATFORM),HISI_3516A) LINUX_SRC = /home/wbk/test/linu

qq_39048131的博客 1231

android 蓝牙通讯demo

android 下蓝牙通讯demo,实现了发现蓝牙,使能蓝牙,通过蓝牙发送消息。

使用OpenMP并行化常见算法

OpenMP并行化常见算法 openmp是强大的并行编译库,可以动态地设置多线程,使用方便。 这里我将以搜索算法为例,介绍如何用OpenMP把常见算法并行化。 旅行商问题 旅行商问题已经老生常谈了。指在有向带权图内,寻找一条最短回路(指经过每个顶点仅一次,且权值总和最小)。事实上该问题是一个NPhard问题,想解决它只能花费指数级的时间复杂度。 我们尝试使用BFS和DFS去求解它。因为题目要求经过...

qq_41858347的博客 3808

visio安装包

Microsoft Office Visio 是一款专业的制图软件。利用经过更新的形状、协作工具和数据链接图表,创建专业级图表以简化复杂的信息。

MPI并行编程计算π值及PSRS排序

什么是MPIMPI(Message Passing Interface)是目前最重要的一个基于消息传递的并行编程工具,它具有移植性好、功能强大、效率高等许多优点,而且有多种不同的免费、高效、实用的实现版本,几乎所有的并行计算机厂商都提供对它的支持,成为了事实上的并行编程标准。MPI是一个库,而不是一门语言,因此对MPI的使用必须和特定的语言结合起来进行。MPI不是一个独立的自包含系统,而是建立在本地

Bonjour~ 9125

WINCC7.3破解文件

WINCC7.3硬件够破解文件,有需要的下载!WINCC7.3硬件够破解文件,有需要的下载!

使用openmp实现快速排序

使用 OpenMP 实现快速排序的基本步骤如下: 在代码的开头添加 OpenMP 头文件 #include <omp.h>。 在要并行化的代码块前添加 #pragma omp parallel 指令,表示这部分代码将并行执行。 在快速排序的主函数中,使用 OpenMP 提供的 omp_get_num_threads() 函数获取当前使用的线程数。 使用 OpenMP 提供的 o...

weixin_35752233的博客 670

CPU作业之openMp实现快速排序

博客原文 欢迎关注博客:GaoMing’s blog 项目介绍 利用OpenMp设计多线程进行快速排序 openMP相关知识 什么是openMP OpenMP是由OpenMP Architecture Review Board牵头提出的,并已被广泛接受的、用于共享内存并行系统的多线程程序设计的一套编译指令 (Compiler Directive)。 OpenMP支持、C、C++和Fortran;而支持OpenMP的编译器包括Sun Compiler、GNU Compiler和Intel Compile

qq_45769678的博客 4764

并行算法:均匀划分(PSRS)和方根划分(SIMD-CREW)

例子:均匀划分技术进行数据的并行排序(N=27,p=3) (a)均匀划分(p1,p2,p3) 22,21,9,87,3,5,18,34,68|70,12,24,7,23,65,89,1,3|43,15,6,16,17,45,67,98,66 (b)局部排序 3,5,9,18,21,22,34,68,87|1,3,7,12,23,24,65,70,89|6,15,16,17,43,45,...

zhangyunfeixyz的博客 2929

并行正则采样排序算法及在 Mars 中的应用

相信大家对排序算法都非常熟悉了,快速排序、堆排序、归并排序等等。如果我们想在一个很大的数据集上进行排序,能利用上多核,甚至是分布式集群,有什么办法么? 本文就介绍一种并行排序算法:并行正则采样排序算法(Parallel Sorting by Regular Sampling),简称 PSRS 算法。 PSRS 算法过程 PSRS 算法的整个过程分为四步,如图所示,我们拆...

数据库技术 666

undefined symbol: omp_get_num_procs错误解决

conda install --channel conda-forge llvm-openmp 上述命令解决了我的烦恼 参考地址

qq_42618228的博客 3364

MPI实现psrs

PSRS(Parallel Sorting by Regular Sampling,并行正则采样排序)的基本原理如下:     begin         (1)均匀划分:将n个元素A[1..n]均匀划分成p段,每个pi处理A[(i-1)n/p+1..in/p]         (2)局部排序:pi调用串行排序算法对A[(i-1)n/p+1..in/p]排序         (3)选取样本

往者不可谏,来者犹可追 4326

MPI-PSRS: 并行正则采样排序算法实现

MPI-PSRS: 并行正则采样排序算法实现 项目介绍 MPI-PSRS 是一个基于 Message Passing Interface (MPI) 的并行正则采样排序算法的开源实现。此项目专注于提供一种高效的数据排序方法,特别适用于大规模数据集的并行处理环境。正则采样排序(PSRS)是一种分布式排序策略,它通过在每个进程中执行局部排序并结合全局的协调步骤来达成整个数据集的有序。项目采用C++编程...

gitblog_01112的博客 535

【MPI OpenMP】并行蒙特卡洛方法求圆周率(C语言)

本文记录了使用MPI与OpenMP两种并行计算方法实现蒙特卡洛计算圆周率,题目是专业实验课上老师给的,主要分享一下自己的做法,希望大家不吝赐教(使用的语言是C语言)。 蒙特卡洛方法求圆周率 蒙特卡洛方法的原理 该方法的原理还是比较简单的,网上资料也有很多,我的实验课老师也提供了一个参考资料,如果大家想看看蒙特卡洛计算圆周率的原理,可以自行查看一下:蒙特卡洛方法求圆周率与定积分及python实现。这位博主分享的写法是python的,并且除了计算了圆周率,还计算了定积分,但我只是查看了其中的原理部分。 为什么

谛凌的博客 3万+
上一篇: TraceMe.exe注册码破解及注册机编写
下一篇: Crack密码验证小实验
rectsuly
博客等级 码龄10年 310粉丝 39原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值