科学网

 找回密码
  注册

tag 标签: 并行计算

相关帖子

版块 作者 回复/查看 最后发表

没有相关内容

相关日志

数字密码锁的快速破解
accsys 2019-11-21 17:45
数字密码锁的快速破解 姜咏江 1 数字密码锁 表 1 黄色底纹部分是一个 10 位的二进制密码锁。表头 X0 至 X9 标明数码的位置。每一行数据叫子句。当设定一组变量值时,子句中至少有一个数码与对应设定的变量值相同,那么这个子句不阻止开锁,否则阻止开锁。显然,当所有的子句都不阻止开锁,那么密码锁就被打开了。表 1 密钥行给出的一组变量值就是这个密码锁的一个密钥。 表 1 一个十位数字密码锁 密钥: 1 1 0 0 1 0 0 0 0 1 码位置: X9 X8 X7 X6 X5 X4 X3 X2 X1 X0 密 码 锁 0 1 1 0 1 0 1 1 1 1 0 0 0 0 0 0 0 0 1 0 1 0 1 1 1 0 0 0 0 1 1 1 0 0 1 由于子句复杂,数量众多,当变量数 N 很大时(例如 N=256 ),用目前最快的计算机要找到密钥,耗费的时间都将无法忍受。除非能够设计出一次能够并行计算 2 N 个数据的处理器。 研究过 P/NP 问题的读者,容易看出,所谓密码锁就是 SAT 问题的二进制表示,密钥就是 SAT 的一个 满足解 。目前的计算机求出 SAT 的满足解,完备算法有 DPLL 方法和暴力破解法。它们都是指数时间复杂度的算法,一般性求出密钥很慢,满足不了实际需要。据说量子计算机可以一次并行计算 2 N 个数据,因而可以快速求出 SAT 的满足解。 现实中,如果有一次对比,就能够找出 2 N 个 N 位数中那些包含一个子句的计算机,那么密码锁也可以象量子计算机一样快得到破解。 2 二进制限位数及性质 限位数是用数码表示位数确定的数。例如二进制数码的位数就固定为 3 。数码 0 不能省略,那么就是 3 位的限位数有 8 个。写出来为: 000 、 001 、 010 、 011 、 100 、 101 、 110 、 111 。 0 和 1 叫互为反码。将对应位置数码相反的限位数叫反码数。显然( 000 、 111 ),( 001 、 110 ), … ,( 011 、 100 )。 子句的反码数叫其反子句。容易证明,一个子句的反子句唯一,非反子句至少有一位数码相同。 表 1 中具有相同变量的子句叫 子句块 。子句块对应变量一组值,使其没有子句阻止开锁,这组值叫子句块的解。由表 1 可见,若子句块无解,该密码锁没有密钥。 用下面的子句块性质,容易找到子句块的解。 性质 :子句块中子句的反子句不在,则这个子句是子句块的解。 证明 :一个子句的反子句是唯一的。若一个子句的反子句不在这个子句块中,其余子句必然与这个子句,至少有一个对应位置数码与该子句数码相同,故这个子句就是该子句块的解。 推论 :属于一个子句块的一对互反子句,都不在所属子句块中,它们都是这个子句块的解。 这个性质可由性质 1 直接推出。 3 求解定理 数字密码锁求出密钥,可以用重要的求解定理。在 N 位二进制数中,一个子句必然包含在一些数中。在 2 N 个 N 位数中,找到包含一个子句的那些数,并消去的方法叫子句包含消去法。全部 N 位数集叫解空间。每个 N 位数叫可能解。 定理: 将子句包含在其中的那些可能解消去 , 解空间中剩余可能解的反码数都是密码锁的密钥。 证明: 因为不在密码锁中的子句,一定都在剩余可能解中,因而剩余的可能解一定包含不在任何子句块中的那些子句。依据性质和推论,剩余可能解的反码数一定包含每个子句块的解,因而剩余可能解的反码数是密钥。定理成立。 4 数据纠缠态 现在的计算机只是用 0 和 1 表示数据。并行计算需要表示 0 、 1 和 空格 。因而需要引入 00 表示 0 , 11 表示 1 ,而用 01 或 10 表示空格(纠缠态)。那么表 1 就可以用两个 N=10 位的二进制数表示一个子句。例如,第一个子句用 0100000000 和 0111111111 来表示。前面两个对应位置是 00 和 11 ,后面对应位置只要是 01 表示即可。 用 0 和 1 的纠缠态表示能够表达任何离散数据,从而将离散数据包含问题,转化成了连续二进制数的运算问题,进而可以用逻辑电路设计出并行运算处理器。 5 并行处理器 SPU 设定离散数据纠缠态表示,依据求解定理,可以实现对 SAT 问题求满足解。 SAT 问题并行处理器 SAT Process Unit(SPU) 的逻辑结构如图 1 所示。如果 N 给变量的子句有 m 个,可将子句被当成纠缠态,那逐一送到子句寄存器,通过一次能够确定 2 N 个 N 位数中是否包含这个子句的 SAT 运算器 SPU ,消去包含子句的可能解,再通过取反就能够得到全部密钥。 图 1 处理器 SPU 6 仿量子计算机 据说 N 位的量子计算机一次能够处理 2 N 个数据。用逻辑电路也能设计一次处理 2 N 个数据的计算机,因而把它叫做仿量子计算机。量子计算机现在并不成熟,何时能够引入应用,恐怕还不好说。仿量子计算机也一次能够处理 2 N 个数据,速度之快当然可以与量子计算机媲美。 仿量子计算机(逻辑结构见图 2 )是在目前的计算机上加增 SPU 处理器,并且依据需要增加了相应的指令系统。该机优点不需要重新建立一套编程应用方式。仿量子计算机有快速和易用的优点。 图 2 仿量子计算机结构 图 2 是以存储设备为中心的计算机设计逻辑, PU 是普通处理器, SPU 是并行处理器, MU 是存储设备。 2019/11/20
个人分类: 数字密码锁|6340 次阅读|0 个评论
PETSc并行计算库
热度 2 plasmascience 2018-7-24 10:38
PETSc 在好几个托卡马克大规模模拟程序(如XGC, GTC)中用到, 变得越来越流行。 PETSc的官方文档里说学习PETSc有很陡的学习曲线,一下子吓走很多人。 PETSc库的一个主要目的是让用户测试各种并行算法变得更容易。 只要懂基本的并行概念, 做过基本的偏微分数值解, 用PETSc一点不难。 我花了一周时间, 读了PETSc 文档及程序例子, 做了一个二维泊松方程的并行数值解, 验证了结果的正确性, 写了一个文档记录: http://theory.ipp.ac.cn/~yj/research_notes/computational_physics.pdf PETSc基本的东西算学会了, 后面打算往正在开发的电磁全粒子程序和GEM里加,改进现有的场求解器。
12220 次阅读|4 个评论
[转载]量子计算入门(2):3分钟了解关键概念
quantumchina 2018-1-7 17:35
量子计算是一种令人兴奋的全新计算模式,它不同于当前数据中心、云环境、PC和其它设备中的数字计算。数字计算需要把数据编码为二进制数字(比特位),每个比特位处于两个确定状态中的一个(0或1)。然而,量子计算使用量子位,后者可以同时处于多个状态。因此,量子位上的操作可以实现并行的大量计算。 从本质上说,量子计算就是并行计算的终极目标,有着攻克传统计算机无解难题的巨大潜力。例如,例如,量子计算机可以模拟自然环境来推进化学、材料科学和分子建模等领域的科研工作。 下面是构成量子计算基础的四个关键概念。 一. 叠加 如果把经典物理学看作一枚硬币,那么这枚硬币不是反面就是正面。比特位类似于此,不是0就是1。在量子物理学中,这枚硬币就像持续旋转中的硬币,同时代表正面和方面。因此,量子位可以同时是0和1,同时上下旋转。 量子态:同时代表多个经典状态 二. 纠缠 纠缠让量子计算能够指数级扩展。如果一个量子位同时代表两个状态,两个量子位结合起来就可以代表四个状态。它们不再被独立看待,而是形成纠缠在一起的超级状态。随着更多量子位链接到一起,状态的数量呈指数级增长,能够为计算机实现天文数字般的计算能力。 两个量子位不再被独立看待,它们形成超级状态 三. 脆弱性 量子态非常脆弱。测量、观察、接触或扰乱任何这些状态,它们就会坍塌成经典状态。这些状态不会坚持很长时间,这也就是为什么目前很难制造量子计算机。 如果被噪声或测量所干扰,量子态会坍塌成经典态 四. 不可克隆 脆弱性的一个推论是“不可克隆定理”。在经典物理中,如果两个比特位由下面的硬币来表示,人们可以复制或窃听和重新创建该信息。相比之下,如果人试图观察或复制一套量子位中的纠缠信息,则这些信息会丢失。量子态无法在发送者或接收者不知情的情况下被复制。这个概念是量子通信的基础。 无法在不破坏量子态的情况下 复制、拦截或窃取 量子计算可以大幅提升性能,有望解决当前的计算机无法解决的具体复杂问题。真正的量子计算机仍处于初级发展阶段,但量子计算有望解决复杂的模拟问题,例如大规模金融分析和更高效的药品开发。 来源链接: http://mp.weixin.qq.com/s?src=11timestamp=1515316956ver=621signature=XzGBKN*aX1oc6BU7k0oLv84Xc0QyHGa43yAVoDEmuSN0IJhoN8NpIiWwVVmXD5Bjbxtwaacl4myk2NhbgGZ-BKyvKBzzTlg7ELVYFJM9JzoLkILyQOQ4rLH1EKgJrjFpnew=1
个人分类: 量子计算|1106 次阅读|0 个评论
Linux:虚拟并行运算环境mpi的配置简介
sanshiphy 2017-4-18 14:56
问题: 有一台电脑, 1 cpu , 超线程 8 核,已安装 Ubuntu 系统。现配置两台虚拟机,每台虚拟机 1cpu , 3 核,两台虚拟机均安装 Ubuntu server 系统,并实现 mpi 并行运算。 思路:利用 vmware 构造虚拟机,利用 ssh 实现不同虚拟机之间的免密码访问,在虚拟机主节点上利用 nfs 服务器设置不同节点之间的共享文件夹。 详情请参考附件: 虚拟并行运算环境mpi的配置v2.0.pdf
个人分类: 技术备忘录|4466 次阅读|0 个评论
[转载]Agisoft Photoscan pro在Linux 系统网络并行平台
cgh 2016-11-10 12:51
Agisoft Photoscan pro在Linux 系统网络并行平台 整理自:http://bbs.dji.com/thread-45301-1-1.html 1、安装Photoscan pro 1.1 使用wget命令直接下载软件包,这是编译好的二进制包。 $~/ wget http://download.agisoft.com/photoscan-pro_1_2_3_amd64.tar.gz 复制代码 1.2 使用tar命令解压软件包 $~/tar -xzvf photoscan-pro_1_2_3_amd64.tar.gz 复制代码 #得到新目录 photoscan-pro, 一般我改名为 psp #pwd命令可以得到当前目录名 1.3 运行photoscan-pro $~/sudo /home/userid/photoscan-pro/photoscan.sh 复制代码 #使用管理员权限运行前面加sudo, 并把userid换成你的用户名 1.4 注册 photoscan-pro 1)$3499USD 购买注册码 https://sites.fastspring.com/agisoft/instant/photoscan_pro 2)或在软件界面选用DEMO模式进行测试使用 2 设置服务器 SERVER 只要一台 $~/sudo /home/userid/photoscan-pro/ photoscan --server --control 192.168.1.100 --dispatch 192.168.1.100 --root /homeuserid/myshare 复制代码 #这边的ip都是服务器ip, --root 后面是你的网络存储点, 请使用cifs或nf挂载mount到你的用户目录下。 3 设置节点 node 最少两台,越多越好 $~/sudo /home/userid/photoscan-pro/photoscan --node --dispatch 192.168.1.100 --root /homeuserid/myshare #这边的ip都是服务器ip, --root 后面是你的网络存储点, 请使用cifs或nfs挂载mount到你的用户目录下。 4 网络存储点 4.1 使用 $~/sudo apt-get cifs-utils #安装网络邻居共享工具包 4.2 挂载共享的目录 $~/sudo mount -t cifs -o username=用户名,password=密码 //网络邻居/共享目录 / homeuserid/myshare 4.3 推荐使用nfs协议吧, 挂载比较简单点, cifs问题多多。 5 在客户端运行Photoscan创建项目并提交计算 5.1 在服务器server上或是任意其他的非node上启动Photoscan pro后, $~/sudo /home/userid/photoscan-pro/ photoscan.sh #在【工具菜单】中选【偏好设置】,出现如下窗口 网络处理要打勾, 主机名就是填入前面设置的服务器server ip, 根就是root ,即网络存储共享点。 5.2 创建chrunks 图片堆, 增加图片, 然后在 【工作流程】 菜单 开始计算。可选批量计算。 5.3 使用 agisoft Network Monitor 查看网络计算情况 psp_ 如果是在服务器上运行的可以控制比如暂停,取消,删除等操作, 使用 --control 192.168.1.100 更改为你的控制电脑的ip。
个人分类: RS|4349 次阅读|0 个评论
使用Matlab MDCS在计算机集群上做并行计算
SilentStorm 2016-1-6 19:28
因为要做大量仿真运算,辗转找到了可以使用的集群。好好研究了如何使用matlab MDCS在集群上做并行运算。现在把过程记录下来,以备将来再用。 我使用的是南安普顿大学的iridis4集群。 此集群使用PBS任务管理系统。 首先需要连接至南安普顿大学的vpn:vpn.soton.ac.uk; 其次使用ssh登录 username@iridis4_c.soton.ac.uk; 1. 找到合适的并行运算模式:这一步可以通过分析自己的代码以及阅读matlab中MDCS的文档找到适用于自己代码的并行运算模式。我的情况是做蒙特卡洛仿真,即数据密集型计算,且循环的每一次运行相互之间是独立的,即前后之间无关。在研究了batch等命令之后,发现batch是我需要的命令。batch可以根据clusterprofile申请资源,clusterprofile中规定了所需要的节点数,每个节点中包含的cpu个数,内存大小,以及预计运行时间。 2. clusterprofile可以在服务器端的matlab的菜单-Parallel-Manage Cluster Profile中定义。先通过import在/local/software/matlab/2014b/extern/examples/MDCS/ 下面的Iridis4_1node,再基于此profile修改并保存为自己需要的profile。注意不可以直接用local(default)那个profile,因为直接用local相当于在服务器的登录节点并行运算. 下面假定我自己定义的profile为 Iridis4_1node_8h 3.使用batch申请一个节点,并使用其16个cpu进行运算: 在m文件中输入: cluster1 = parcluster('Iridis4_1node_8h'); job = batch(cluster1,@ARsplitRunParforTriFreq,1,{ep,num,N},'Pool',15); 其中 ARsplitRunParforTriFreq.m为需要并行运算的函数,里面包含parfor语句。 1是 ARsplitRunParforTriFreq函数的输出参数个数, {ep,num,N}为 ARsplitRunParforTriFreq函数的输入参数。 ‘Pool’,15表示除了一个 master matlab之外,还有15个slave matlab要运行,总共是16个cpu。 ARsplitRunParforTriFreq.m文件内容为: function outsolution= ARsplitRunParforTriFreq(ep,num,N) parfor i=1:N blah blah blah end return 4. 再通过for循环批量提交batch作业,申请多个节点 5. parfor 命令进行并行循环,请参见matlab帮助。 注意事项: job = batch(cluster1,@ARsplitRunParforTriFreq,1,{ep,num,N},'Pool',15); 此语句中的 1表示的是函数 ARsplitRunParforTriFreq的输出参数个数,不是输入参数个数。如果搞错了的话,matlab虽然会申请到16个cpu运算,但是进不去 ARsplitRunParforTriFreq函数。表现出来的现象是:16个matlab进程 会同时闪退,而且不输出任何东西。妈的,调了3天才找到这个错误。。。
个人分类: 计算机|8557 次阅读|1 个评论
[转载]如何在Jetson TK1上安装Caffe深度学习库
alaclp 2015-12-3 13:53
Caffe 的创造者 Yangqing Jia ,最近花了些时间在NVIDIA Jetson 开发板上运行 caffe 框架。 Jetson TK1 有 192 个 CUDA 核,是非常适用于深度学习这种计算任务的。未来,如果我们想在移动设备上做一些事情的话, Jetson 是一个不错的选择,而且它预装 Ubuntu 操作系统,因此也是非常易于开发的。 Caffe内置了Alexnet模式,这是Imagenet-winning 架构的一个版本,可以识别1000 个不同种类的物体。用这个作为一种 benchmark , Jetson 可以在 34ms 里分析一个图像。 接下来,介绍如何在Jetson 上安装并运行 Caffe. 安装 你从盒子里拿到Jetson 的第一步是登录。你可以接一个显示器和键盘,但我倾向于你将它跟一个本地路由连接,然后 ssh 访问。 elinux.org/Jetson/Remote_Access 上有具体的步骤(不明白的地方可以在我们的QQ 技术群里询问) ,这时候在你的本地网络上会出现 tegra-ubuntu.local , username 是ubuntu: ssh ubuntu@tegra-ubuntu.local 默认密码是 ubuntu,接下来我们需要安装NVIDIA 的驱动,然后重启: sudo NVIDIA-INSTALLER/installer.sh sudo shutdown -r now 一旦开发板重启后,你可以登录进去,然后继续安装Caffe 所需的环境: ssh ubuntu@tegra-ubuntu.local sudo add-apt-repository universe sudo apt-get update sudo apt-get install libprotobuf-dev protobuf-compiler gfortran \ libboost-dev cmake libleveldb-dev libsnappy-dev \ libboost-thread-dev libboost-system-dev \ libatlas-base-dev libhdf5-serial-dev libgflags-dev \ libgoogle-glog-dev liblmdb-dev gcc-4.7 g++-4.7 你需要安装 Cuda SDK 以建立和运行GPU程序 ( CUDA 环境安装步骤都已经放在 QQ 技术群里,安装过程有任何问题,请随时在群里提出)。 如果一切顺利,你运行‘nvcc -V可以看到一个完整的编译器版本信息。这个时候你需要安装Tegra 版本的 OpenCV. ( 安装步骤同样在 QQ 群里找) 我们需要下载并安装Caffe sudo apt-get install -y git git clone https://github.com/BVLC/caffe.git cd caffe git checkout dev cp Makefile.config.example Makefile.config sed -i s/# CUSTOM_CXX := g++/CUSTOM_CXX := g++-4.7/ Makefile.config 我们必须使用gcc 4.7 版本,因为默认 4.8 会有一些问题。你应该可以完成整个安装。 make -j 8 all 一旦完成这可,你可以运行一下Caffe 的测试包来检查是否安装成功。这个可能需要花费一些时间,但希望一切顺利。 make -j 8 runtest 最后,你可以运行一下Caffe 的基准代码来检测一下性能。 build/tools/caffe time --model=models/bvlc_alexnet/deploy.prototxt --gpu=0 这个可能需要花费30 秒,输出一组统计数字。它运行 50 迭代的识别 pipleline 。每个分析 10 个不同的输入图像。因此看一下“‘ Average Forward pass ”时间,然后除以 10 就可以得到每个识别时间。我的结果是 337.86ms ,所以每个图像大概是 34ms 。你也可以把 -gpu=0 的标志去掉,看一下 CPU 的结果。在我这里看是大概 585ms ,所以你看 CUDA 还是起到作用了。 来源:http://www.gpus.cn/qianduan/front/getNewsArc?articleid=83
个人分类: GPU|3092 次阅读|0 个评论
[转载]R语言并行计算案例
zhangdong 2014-11-25 15:34
source: http://stackoverflow.com/questions/24347675/parallel-version-of-transform-or-mutate-in-r Parallel version of transform (or mutate) in R_ - Stack Overflow.pdf
2128 次阅读|0 个评论
Turbomole并行计算
niuyingli 2014-4-23 15:18
测试
个人分类: Turbomole|0 个评论
学习FORTRAN加MPI进行并行计算
热度 1 cambaluc 2013-4-17 11:54
编译环境的配置在linux下容易点,到windows下有点烦琐,首先,我的两台64位机不支持CompaqVFortran,兼容条件下勉强安装,但编译还是有问题,再转到只有两核的32位机XP系统下,先装CVFortran,再下载安装Microsoft .Net Framework,用的是dotnetfx35setup2.exe.再从www.mpich.org/downloads/下载安装MPICH2,用的是mpich2-1.4.1p1-win-ia32.msi。配置时主要指明include和lib库文件的路径. linux下编译: $ mpif90 -o matrix matrix_parallel.f 运行: $ mpirun -np 8 ./matrix windows下命令行运行: mpiexec -np 8 matrix.exe 以下是一个矩阵乘法的fortran程序片段,主要调用mpi的几个函数,已在redhat linux和winXP下调试通过,但愿对大家有帮助,也请发表批评. program main use mpi integer TM,TL,TN,ierr integer MASTER integer FROM_MASTER,FROM_WORKER integer status(MPI_STATUS_SIZE) parameter (TM=180,TL=150,TN=2000) parameter (MASTER=0,FROM_MASTER=1,FROM_WORKER=2) integer numtasks,taskid,numworkers,source,dest integer mtype,cols,numelemt integer AVGCOL,extra,offset,offset1,i,j,k double precision a(TM,TL),b(TL,TN),c(TM,TN) call MPI_INIT( ierr ) call MPI_COMM_RANK( MPI_COMM_WORLD, taskid, ierr ) call MPI_COMM_SIZE( MPI_COMM_WORLD, numtasks, ierr ) numworkers=numtasks-1; cccccccccccccccccccccccccccccccccMASTERcccccccccccccccccccccccccccccc IF(taskid.EQ.MASTER) THEN WRITE(*,*)'Number of worker tasks= ',numworkers DO i=1,TM,1 DO j=1,TL,1 a(i,j)=i+j ENDDO ENDDO DO i=1,TL,1 DO j=1,TN,1 b(i,j)=(i-1)*(j-1) ENDDO ENDDO AVGCOL=TN/numworkers write(*,*) 'AVGCOL',AVGCOL extra=mod(TN,numworkers) write(*,*) 'extra',extra offset=1 mtype=FROM_MASTER do dest=1,numworkers,1 IF(dest.LE.extra) THEN cols=AVGCOL+1 ELSE cols=AVGCOL; ENDIF WRITE(*,*) 'SEND',cols,'cols to task ',dest call MPI_SEND(offset,1,MPI_INT,dest,mtype,MPI_COMM_WORLD,ierr) call MPI_SEND(cols,1,MPI_INT,dest,mtype,MPI_COMM_WORLD,ierr) numelemt=TM*TL call MPI_SEND(a(1,1),numelemt,MPI_DOUBLE_PRECISION,dest,mtype,MPI_COMM_WORLD,ierr) numelemt=TL*cols call MPI_SEND(b(1,offset),numelemt,MPI_DOUBLE_PRECISION,dest,mtype,MPI_COMM_WORLD,ierr) offset=offset+cols enddo mtype=FROM_WORKER do i=1,numworkers source=i; call MPI_RECV(offset,1,MPI_INT,source,mtype,MPI_COMM_WORLD,status,ierr) call MPI_RECV(cols,1,MPI_INT,source,mtype,MPI_COMM_WORLD,status,ierr) numelemt=TM*cols call MPI_RECV(c(1,offset),numelemt,MPI_DOUBLE_PRECISION,source,mtype,MPI_COMM_WORLD,status,ierr) enddo c write(*,*) c write(*,100) ((c(i,j),j=1,TN),i=1,TM) c write(*,100) c(TM,TN) 100 FORMAT(1X,4G15.3) write(*,*) ENDIF IF(taskid.GT.MASTER) THEN mtype=FROM_MASTER; source=MASTER; call MPI_RECV(offset,1,MPI_INT,source,mtype,MPI_COMM_WORLD,status,ierr) offset1=offset call MPI_RECV(cols,1,MPI_INT,source,mtype,MPI_COMM_WORLD,status,ierr) numelemt=TM*TL; call MPI_RECV(a(1,1),numelemt,MPI_DOUBLE_PRECISION,source,mtype,MPI_COMM_WORLD,status,ierr) numelemt=TL*cols; call MPI_RECV(b(1,1),numelemt,MPI_DOUBLE_PRECISION,source,mtype,MPI_COMM_WORLD,status,ierr) do i=1,TM,1 do j=1,cols c(i,j)=0.0 do k=1,TL c(i,j)=c(i,j)+a(i,k)*b(k,j) enddo enddo enddo mtype=FROM_WORKER; call MPI_SEND(offset1,1,MPI_INT,MASTER,mtype,MPI_COMM_WORLD,ierr) call MPI_SEND(cols,1,MPI_INT,MASTER,mtype,MPI_COMM_WORLD,ierr) numelemt=TM*cols call MPI_SEND(c(1,1),numelemt,MPI_DOUBLE_PRECISION,MASTER,mtype,MPI_COMM_WORLD,ierr) endif call MPI_FINALIZE(ierr) end
个人分类: FORTRAN|17212 次阅读|3 个评论
[转载]科学计算常用的基础并行求解软件库介绍
qlearner 2012-12-31 09:39
Trilinos:解决大规模、复杂物理工程和科学应用的面向对象的软件框架下开发并行解决算法和数学库。 PETSc:用于在分布式存储环境高效求解偏微分方程组及相关问题,包括很多并行线性和非线性方程求解器。 TAO:在高性能计算机上求解大规模最优化问题。 SLEPc:可并行求解大型稀疏矩阵特征问题。 以上三者的功能近似。 SUNDIALS:用于求解非线性微分/代数方程。 Hypre:用于大规模并行计算机上求解大型稀疏线性方程组。 ScaLAPACK:可扩展线性代数程序包。 SuperLU:大型稀疏矩阵直接求解器。
个人分类: 编程学习|2387 次阅读|0 个评论
CUDA简单介绍(一)
jameshzd 2012-10-25 01:31
下面对CUDA和GPU做几个声明: GPU是作为CPU的“辅助计算设备”来使用的。也就是说,在CPU上效率较低的大规模的平行计算模块可以放入GPU中去执行,能增加整体的速度。但是千万不要讲原来CPU上很快的串行代码也奢望放到GPU上。不仅比较困难,也没有太大的帮助。“术业有专攻”,这句话不无道理。 CUDA C是C语言的超集(superset),也就是说,.cu的CUDA程序最根本的它是一个C程序,所有C语言中的语法都可以再CUDA C中实现。 要想用好CUDA,先想想我们要把一只大象装进一个冰箱里面冷冻,并且在将大象冻僵之后取出。需要什么条件?以及具体的步骤。 先说说条件: 一只大象(这是必须的,如果连大象都没有,何谈装呢?) 一个有门的冰箱(同理) 下面开始谈方法: 将冰箱的门打开 把大象塞进去 等待冷却。。。 把冰箱门打开 把大象取出来。 可能大家觉得我在说废话。但是GPU中很重要的命令恰巧可以和这些基本操作互相对应,下面我来一一讲解: 要有冰箱:这就要求我们要在GPU上为数据开辟一段内存空间。所用的指令就是 cudaMalloc((void**)pointer_name,size) ;size是所需要alloc内存的大小,pointer_name就是指向GPU内存的指针(在申请指针名的时候,最好将device端和host端的指针分开,否则有的时候会乱掉。)。而且这样也能保证我们在传指针到kernel函数的时候不至于出错(kernel函数只接受GPU上的内存指针)。 把大象塞进去:要求我们有从CPU到GPU的管道。这个函数式 cudaMemcpy(to,from,size,enum) ;其中的to代表数据传向的指针,from代表数据开始的指针,size是大小,enum是一个枚举量,它有四种不同的值,分别是:cudaMemcpyDeviceToHost(数据从GPU传向CPU);cudaMemcpyHostToDevice(数据从CPU传向GPU);cudaMemcpyHostToHost(数据从CPU传向CPU);cudaMemcpyDeviceToDevice(数据从GPU传向GPU);有了这个函数,我们CPU到GPU的通道就解决了。当然,更细致的时候我们还知道,GPU在这里的内存是global memory。在GPU端,内存的架构和内部的调度非常复杂。需要另外一篇博文来认真的探讨。 等待冷却:GPU中有了数据后,我们就可以在上面进行运算操作了。这也就是GPU计算最核心的部分。如何在GPU上进行有效的线程管理,如何利用SM中的share memory和SP中的register。这是作为一个高级GPU开发者必须要掌握的基本知识,无奈现在我还没有掌握。但是或许在几个星期以后,我能把它搞懂!在这里需要注意的一个语法是kernel函数的定义,kernel函数是在CPU端调用GPU端代码的一个入口,kernel有多种写法,每种写法都有不同的含义: __global__ void kernel(para) ;前面的前缀除了__global__之外还有__host__,__device__,__host__ and __device__这几种。__global__函数是指在CPU上调用,在GPU上执行的函数。__host__指的是在CPU上调用,在CPU中执行的,__device__指的是在GPU上调用,在GPU上执行的。 把大象取出来:这和把大象塞进去是运用的同样的通道,这里就不再赘述了。 如果嫌冰箱太麻烦的话(在编程中推荐这么做,因为下次再启动的时候就又有一块干净的内存了): cudaFree(pointer_onGPU) 。将你一开始alloc的那些memory给释放掉。 再过两天会将最重要的GPU里面的内存以及调度问题整理成一篇博文发表,请大家关注~~ 其实CUDA C的语言是很好学的,跑几个程序就能得到结果了。最重要的不是说我们要学一门语言,最重要的是学习并行计算的思路以及如何进行数据的并行化处理。将大量的计算过程拆分成很多平行处理的单元(当然,单元之间可以有相互的作用:1 block内部的thread之间可以互相交互)。这是CUDA学习的核心,也是最困难的地方。以上是我对于CUDA C语言的一些基本结构的理解。十分浅显,我也在努力的学习着。 On the way~~~
个人分类: 并行计算|5374 次阅读|0 个评论
[转载]浅谈多核CPU、多线程与并行计算
ywk1573 2012-6-3 14:22
0.前言 最近发觉自己博客转帖的太多,于是决定自己写一个原创的。笔者用过MPI和C#线程池,参加过比赛,有所感受,将近一年来,对多线程编程兴趣一直不减,一直有所关注,决定写篇文章,算是对知识的总结吧。有说的不对的地方,欢迎各位大哥们指正:) 1.CPU发展趋势 核心数目依旧会越来越多,依据摩尔定律,由于单个核心性能提升有着严重的瓶颈问题,普通的桌面PC有望在2017年末2018年初达到24核心(或者16核32线程),我们如何来面对这突如其来的核心数目的增加?编程也要与时俱进。笔者斗胆预测,CPU各个核心之间的片内总线将会采用4路组相连:),因为全相连太过复杂,单总线又不够给力。而且应该是非对称多核处理器,可能其中会混杂几个DSP处理器或流处理器。 2.多线程与并行计算的区别 (1)多线程的作用不只是用作并行计算,他还有很多很有益的作用。 还在单核时代,多线程就有很广泛的应用,这时候多线程大多用于降低阻塞 (意思是类似于 while(1) { if(flag==1) break; sleep(1); } 这样的代码) 带来的CPU资源闲置,注意这里没有浪费CPU资源,去掉sleep(1)就是纯浪费了。 阻塞在什么时候发生呢?一般是等待IO操作(磁盘,数据库,网络等等)。此时如果单线程,CPU会干转不干实事(与本程序无关的事情都算不干实事,因为执行其他程序对我来说没意义),效率低下(针对这个程序而言),例如一个IO操作要耗时10毫秒,CPU就会被阻塞接近10毫秒,这是何等的浪费啊!要知道CPU是数着纳秒过日子的。 所以这种耗时的IO操作就用一个线程Thread去代为执行,创建这个线程的函数(代码)部分不会被IO操作阻塞,继续干这个程序中其他的事情,而不是干等待(或者去执行其他程序)。 同样在这个单核时代,多线程的这个消除阻塞的作用还可以叫做“并发”,这和并行是有着本质的不同的。并发是“伪并行”,看似并行,而实际上还是一个CPU在执行一切事物,只是切换的太快,我们没法察觉罢了。例如基于UI的程序(俗话说就是图形界面),如果你点一个按钮触发的事件需要执行10秒钟,那么这个程序就会假死,因为程序在忙着执行,没空搭理用户的其他操作;而如果你把这个按钮触发的函数赋给一个线程,然后启动线程去执行,那么程序就不会假死,继续相应用户的其他操作。但是,随之而来的就是线程的互斥和同步、死锁等问题,详细见 有关文献 。 现在是多核时代了,这种线程的互斥和同步问题是更加严峻的,单核时代大都算并发,多核时代真的就大为不同,为什么呢?具体细节请参考 有关文献 。我这里简单解释一下,以前volatile型变量的使用可以解决大部分问题,例如多个线程共同访问一个Flag标志位,如果是单核并发,基本不会出问题(P.S.在什么情况下会出问题呢?Flag有多个,或者是一个数组,这时候只能通过逻辑手段搞定这个问题了,多来几次空转无所谓,别出致命问题就行),因为CPU只有一个,同时访问这个标志位的只能有一个线程,而多核情况下就不太一样了,所以仅仅volatile不太能解决问题,这就要用到具体语言,具体环境中的“信号量”了,Mutex,Monitor,Lock等等,这些类都操作了硬件上的“关中断”,达到“原语”效果,对临界区的访问不被打断的效果,具体就不解释了,读者可以看看《现代操作系统》。 (2)并行计算还可以通过其他手段来获得,而多线程只是其中之一。 其他手段包括:多进程(这又包括共享存储区的和分布式多机,以及混合式的),指令级并行。 ILP(指令级并行) ,x86架构里叫 SMT(同时多线程) ,在MIPS架构里与之对应的是 super scalar(超标量) 和乱序执行,二者有区别,但共同点都是可以达到指令级并行,这是用户没法控制的,不属于编程范围,只能做些有限的优化,而这有限的优化可能只属于编译器管辖的范畴,用户能做的甚少。 (3)典型的适于并行计算的语言 Erlang 和 MPI :这两个前者是语言,后者是C++和Fortran的扩展库,效果是一样的,利用多进程实现并行计算,Erlang是共享存储区的,MPI是混合型的。 C#.NET4.0 :新版本4.0可以用少量代码实现并行For循环,之前版本需要用很繁琐的代码才能实现同样功能。这是利用了多线程实现并行计算。Java和C#3.5都有线程池(ThreadPool),也是不错的很好用的多线程管理类,可以方便高效的使用多线程。 CUDA,还是个初生牛犊,有很大的发展潜力,只不过就目前其应用领域很有限。其目前只能使用C语言,而且还不是C99,比较低级,不能使用函数指针。个人感觉这由于硬件上天生的局限性(平均每个核心可用内存小,与系统内存通讯时间长),只适用于做科学计算,静态图像处理,视频编码解码,其他领域,还不如高端CPU。等以后GPU有操作系统了,能充分调度GPU资源了,GPU就可以当大神了。游戏中的物理加速,实际上多核CPU也能很好的做到。 其他语言。。。恩。。留作将来讨论。 3.线程越多越好吗?什么时候才有必要用多线程? 线程必然不是越多越好,线程切换也是要开销的,当你增加一个线程的时候,增加的额外开销要小于该线程能够消除的阻塞时间,这才叫物有所值。 Linux自从2.6内核开始,就会把不同的线程交给不同的核心去处理。Windows也从NT.4.0开始支持这一特性。 什么时候该使用多线程呢?这要分四种情况讨论: a.多核CPU——计算密集型任务。此时要尽量使用多线程,可以提高任务执行效率,例如加密解密,数据压缩解压缩(视频、音频、普通数据),否则只能使一个核心满载,而其他核心闲置。 b.单核CPU——计算密集型任务。此时的任务已经把CPU资源100%消耗了,就没必要也不可能使用多线程来提高计算效率了;相反,如果要做人机交互,最好还是要用多线程,避免用户没法对计算机进行操作。 c.单核CPU——IO密集型任务,使用多线程还是为了人机交互方便, d.多核CPU——IO密集型任务,这就更不用说了,跟单核时候原因一样。 4.程序员需要掌握的技巧/技术 (1)减少串行化的代码用以提高效率。这是废话。 (2)单一的共享数据分布化:把一个数据复制很多份,让不同线程可以同时访问。 (3)负载均衡,分为静态的和动态的两种。具体的参见 有关文献 。 原文为: http://blog.csdn.net/delacroix_xu/article/details/5928121
个人分类: 并行计算|4345 次阅读|0 个评论
并行计算中的随机数产生问题
热度 1 haijunzhouitp 2012-5-29 21:49
只会做一点最简单的数值计算。一直用一个比较慢的随机数生成程序,它不适合于并行计算环境。 几年以前,读过Heiko Bauke和Steven Mertens的论文,知道他们开发了一个并行随机数软件包, 称为TRNG (是Tina's Random Number Generator的缩写)。 这几天仔细阅读了该软件包的使用手册,也请我的一位同事将它安装到我们的微型并行计算机系统了。 发现它真的很好,值得推荐。推荐理由如下: a) 有N种不同的随机数产生器,N --infty! b) 提供block splitting及leapfrog功能(这样一个随机数序列可以分配给任意多个进程):这分别通过jump及split函数实现; c) ... d) ... 软件包的下载地址为: http://numbercrunch.de/trng/ 如果您在使用时有心得体会,请一定要教我。 一个简单的应用程序(目的是理解随机数产生器的一种调用方式,以及split 函数的应用): ==== #include cmath #include fstream #include iostream #include string #include valarray #include trng/lcg64_shift.hpp #include trng/uniform01_dist.hpp #include "mpi.h" using namespace std; class mytest { public: test(trng::lcg64_shift , trng::lcg64_shift); void simulation(const string ); private: trng::lcg64_shift PRNG; trng::lcg64_shift PRNG2; trng::uniform01_dist uprn; }; int main(int argc, char ** argv) { int number_of_processes, my_rank; MPI_Init(argc, argv); MPI_Comm_size(MPI_COMM_WORLD, number_of_processes); MPI_Comm_rank(MPI_COMM_WORLD, my_rank); if(number_of_processes!=8) exit(1); valarraystring ofilename("t00.dat",number_of_processes); ofilename ="t00.dat"; ofilename ="t01.dat"; ofilename ="t02.dat"; ofilename ="t03.dat"; ofilename ="t04.dat"; ofilename ="t05.dat"; ofilename ="t06.dat"; ofilename ="t07.dat"; trng::lcg64_shift PRNG, PRNG2; //定义两个随机数产生器 PRNG.split(number_of_processes, my_rank); //将PRNG的序列leapfrog 到不同的进程 mytest uniformrd(PRNG , PRNG2 ); uniformrd.simulation(ofilename ); MPI_Finalize(); return 0; } mytest::mytest(trng::lcg64_shift rd, trng::lcg64_shift rd2) { PRNG=rd; PRNG2=rd2; return ; } void my::simulation(const string ofilename) { ofstream output(ofilename.c_str() ); output.precision(16); for(int i=0; i10; ++i) outputuprn(PRNG)endl; outputendlendlendl; for(int j=0; j10; ++j) { for(int i=0; i8; ++i) outputuprn(PRNG2)endl; outputendl; } output.close(); return ; }
个人分类: 有所思|6459 次阅读|1 个评论
云计算的前世今生(二)
热度 3 ywan 2011-4-7 23:46
“云计算”的 上半身,或者说用户端, 其实就是计算机虚拟机技术充分使用。从用户角度来讲,总是希望自己的硬件资源能够被充分利用。所以虚拟机技术很快得到了推广和应用。不过最初的虚拟机技术是以单机服务器为主 – 不管是 IBM 还是 VMware 一开始所做的,都是在单机服务器的硬件资源上提供虚拟机服务。而当企业拥有大量服务器时,这种一个一个的单机利用方式显然还不够理想。我们会很自然地想到,如果能够将所有的服务器资源整合到一起,然后统一使用岂不更好?这就牵扯到了“云计算”服务端部分,或者说“云端部分”。 事实上,这个想法在技术上早已经实现了,这就是包括“分布计算”,“并行计算”和“网格计算”在内的,将若干单机通过联网方式合并到一起来产生巨大计算能力的一种系统技术。而这种做法的最初动机是为了省钱 — 提高经济效益。譬如,搞天文的科学家们发现他们需要分析从外太空收集的海量信号信息,但却没有足够的资金购买大型机来进行分析(事实上,即便有几台大型机可能也远不够用的),于是广泛“发动群众”通过分布式计算技术来解决这个问题。这就是 1999 年出台的有名的 SETI@Home 。我当时也下载了一个 SETI@Home 的屏保程序到自己办公室的电脑上,每天早晨一进办公室,就可以看到自己的机器昨晚处理了多少个数据包,发现了什么新东西。挺有意思、颇有“成就感”呢。 SETI@Home 的成功之处,在于激发了大家的想象空间,有几个商业嗅觉比较敏锐的人发现此法似乎可以赚钱,于是,搞了类似的客户端程序,一边鼓励群众下载,另一边跟大型制药公司等需要进行海量计算的企业联系。不过,后来发现可操作性有限,主要是众多企业增加了对计算机安全性的考量,他们不希望自己雇员的计算机没事儿时运行这些东西。大学里的计算机倒是不受限制,不过毕竟数量不够,制药公司的项目不像 SETI@Home ,前者还是有比较明确的时间限制的。 同“分布计算”在 SETI@home 项目上的成功相比,“并行计算”在企业里的应用就显得非常成熟。这主要是因为两者需要解决的技术难题不同。前者研究的是如何将不同的计算机资源联合到一起,这些计算机可能从硬件架构到操作系统软件都完全不同,所以整合后的效率不会太高。事实上,我们的整个互联网亦可以看作是一个巨型的(无清晰目标的?)分布式计算系统。而后者则可以从比单机更底层的硬件 --- 比如 CPU 上来整合 – - 现在英特尔推出的多核 CPU 就需要“并行计算”的理论来研究如何充分利用其多核资源。再往上升一点, Wintel 服务器的多 CPU 系统也是“并行计算”的一种类型。众多的软件公司也往往根据企业用户的服务器的 CPU 的数目多少来给其软件定价。 企业自己搞的“并行计算”多半是在单机层面上展开的,这主要是成本低。所以也是一种“分布式计算”,不过跟 SETI@Home 等分布式计算相比,企业的单机往往都是同一型号的成百上千的“克隆”而已,所以,其硬件利用效率要比分布式计算的不同机种整合高很多。在这方面做的最成功的公司之一就是大名鼎鼎的“谷歌”了。
个人分类: 互联网|3904 次阅读|3 个评论
“显卡计算”与“天河1号”
热度 1 seawan 2011-3-24 19:51
我真是孤陋寡闻。今天听一个老同学说,我国的“天河1号”现在是世界超算第一名了。 我上网查查,果然。2700多万亿次/秒,第一。 而“显卡计算”这样技术,就是超级计算机背后的动力。 据说天河1号就是这样的,有无数个NVidia显卡组成的一个并行CPU+GPU群。 也就是说,现在的超级计算机,已经不再是超级CPU的同义词了,而是“显卡群”的同义词? 另外,在NVidia的网站的图片上,可以看到对Java/Pathon的支持。但是,在软件下载的区域,却只有C/C++。Why? 找了半天,才发现下面链接: Java wrapper jCUDA: Java for CUDA Bindings for CUDA BLAS and FFT JaCUDA .NET integration for CUDA Thrust: C++ template Library for CUDA CuPP : C++ framework for CUDA Libra: C/C++ abstraction layer for CUDA F# for CUDA
个人分类: 并行计算|3801 次阅读|1 个评论
2009春季《并行计算理论》课件
热度 1 light 2009-6-15 09:32
课程论坛(作业、问题讨论、通知) http://groups.google.com/group/yinliang_zhao?lnkpli=1 考试题 考试题 课件(本课件中部分内容来自其他大学的同名课件,主要有:中国科学技术大学陈国良教授、Rice大学、Stanford大学、Berkley大学、MIT等,在此表示感谢) 第一章 第二章 第三章 第四章 第六章 第七章 第九章 第十二章 第十三章 第十四章
个人分类: 课程资料|5461 次阅读|0 个评论

Archiver|手机版|科学网 ( 京ICP备07017567号-12 )

GMT+8, 2024-4-30 21:31

Powered by ScienceNet.cn

Copyright © 2007- 中国科学报社

返回顶部