Some problems in openMP's parallel for
Overview
Somehow I started preparing for the ASC competition.
When I’m trying my second demo pi, which is a program running Monte-Carlo algorithm with multi-threading tech, I encountered a question.
Question-Solution
1. Initial program
// pi.cpp
#include <iostream>
#include <fstream>
#include <omp.h>
using namespace std;
fstream fin("/dev/urandom", ios::in|ios::binary);
u_int32_t randomNum() {
u_int32_t ret;
fin.read((char*)&ret, sizeof(u_int32_t));
return ret;
}
int main() {
int64_t inCircleHits = 0;
int64_t totalHits = 1000000;
#pragma omp parallel for num_threads(4) reduction(+:inCircleHits)
for (int i=1 ; i<=totalHits ; i++) {
double x=1.0*randomNum()/__UINT32_MAX__;
double y=1.0*randomNum()/__UINT32_MAX__;
if ((x*x+y*y)<=1.0) {
inCircleHits++;
}
}
clog << 4.0*inCircleHits/totalHits << endl;
fin.close();
return 0;
}
Running environment and results:
LLVM-clang++ + external openMP library on macOS: 3.9969 (always 3.9+)
GCC-g++ + built-in openMP library on macOS: 10: Bus Error
GCC-g++ + built-in openMP library on linux: Segmentation fault(core dumped)
Analysis: ??? (Browse online for a couple of hours…)
Gain discovery: On the Internet tutorials & examples, the loop variables are always inititialized with 0
.
2. Second Trial
At this time, I initialized the loop variable i
with 0
for (int i=0 ; i<totalHits ; i++)
Running environment and results:
LLVM-clang++ + external openMP library on macOS: 3.9925 (always 3.9+)
GCC-g++ + built-in openMP library on macOS: 3.9912 (always 3.9+)
GCC-g++ + built-in openMP library on linux: Segmentation fault(core dumped)
Analysis: Errr… at least we fixed a internal exception.
But why do the answers incorrect? And why does it fails on Linux platform?
Hypothesis: Maybe std::fstream
is to blame. The objects in c++ (may be) not multiThread-safe.
Trial 3
Try substitute std::fstream
with the old friend FILE *
Changed all cpp to c
// pi.c
#include <stdio.h>
#include <stdlib.h>
#include <omp.h>
FILE *randomFile;
u_int32_t randomNum() {
u_int32_t ret;
fread((char*)(&ret), sizeof(u_int32_t), 1, randomFile);
return ret;
}
int main() {
randomFile = fopen("/dev/urandom", "rb");
int64_t inCircleHits = 0;
int64_t totalHits = 1000000;
#pragma omp parallel for num_threads(4) reduction(inCircleHits)
for (int i=0 ; i<totalHits ; i++) {
double x=1.0*randomNum()/__UINT32_MAX__;
double y=1.0*randomNum()/__UINT32_MAX__;
if ((x*x+y*y)<=1.0) {
inCircleHits++;
}
}
printf("%f", 4.0*inCircleHits/totalHits);
fclose(randomFile);
fflush(stdout);
return 0;
}
Running environment and results:
LLVM-clang++ + external openMP library on macOS: 3.135 (correct)
GCC-g++ + built-in openMP library on macOS: 3.141 (correct)
GCC-g++ + built-in openMP library on linux: 3.132 (correct)
Yea. As we could see, it’s running well.
4. variable control
Let’s see what happens if we initialize loop variable i
with 1
for (int i=1 ; i<=totalHits ; i++)
Running environment and results
LLVM-clang++ + external openMP library on macOS: (correct)
GCC-g++ + built-in openMP library on macOS: (correct)
GCC-g++ + built-in openMP library on linux: (correct)
So, the loop variable isn’t the decicive factor, std::fstream
is!
Conclusion
Do not ever use cpp’s objects unless you make sure it’s safe under a multiThreading context.
Some problems in openMP's parallel for的更多相关文章
- Introduction to Parallel Computing
Copied From:https://computing.llnl.gov/tutorials/parallel_comp/ Author: Blaise Barney, Lawrence Live ...
- openmp 的使用
http://blog.csdn.net/gengshenghong/article/details/7003110 说明:这部分内容比较基础,主要是分析几个容易混淆的OpenMP函数,加以理解. ( ...
- 并行计算之OpenMP入门简介
在上一篇文章中介绍了并行计算的基础概念,也顺便介绍了OpenMP. OpenMp提供了对于并行描述的高层抽象,降低了并行编程的难度和复杂度,这样程序员可以把更多的精力投入到并行算法本身,而非其具体实现 ...
- OpenMP并行程序设计
1.fork/join并行执行模式的概念 2.OpenMP指令和库函数介绍 3.parallel 指令的用法 4.for指令的使用方法 5 sections和section指令的用法 1.fork/j ...
- 通过 GCC 学习 OpenMP 框架
OpenMP 框架是使用 C.C++ 和 Fortran 进行并发编程的一种强大方法.GNU Compiler Collection (GCC) V4.4.7 支持 OpenMP 3.0 标准,而 ...
- [转]OpenMP中几个容易混淆的函数(线程数量/线程ID/线程最大数)以及并行区域线程数量的确定
说明:这部分内容比较基础,主要是分析几个容易混淆的OpenMP函数,加以理解. (1)并行区域数量的确定: 在这里,先回顾一下OpenMP的parallel并行区域线程数量的确定,对于一个并行区域,有 ...
- [转载]John Burkardt搜集的FORTRAN源代码
Over the years, I have collected, modified, adapted, adopted or created a number of software package ...
- 竞态条件 race condition data race
竞态条件 race condition Race condition - Wikipedia https://en.wikipedia.org/wiki/Race_condition A race c ...
- Fortran并行计算的一些例子
以下例子来自https://computing.llnl.gov/tutorials/openMP/exercise.html网站 一.打印线程(Hello world) C************* ...
随机推荐
- react项目创建流程
react 项目搭建 系统: windows 1.安装 node node 下载地址.一路 next 如果遇到 windows 没有权限安装 msi 文件.打开 cmd,运行msiexec /pack ...
- Linux NSF网络共享盘
服务器安装: yum -y install nfs-utils rpcbind 服务器配置 :vi /etc/exports 例: /root/docs 192.168.1.*(rw,sync,no ...
- windows10 + docker利用文件映射进行编程开发
0. 以安装swoole框架"easyswoole"举例,建议使用powershell或者cmder输入命令 1. 首先准备好window10专业版开启Hyper-V,然后下载 ...
- Sequence(Poj2442)
Sequence(Poj2442) 题意: 有m个数列,每个数列n个值,每个序列中选取一个值可以组成n^m种不同的序列,求前n小的序列和. Input 12 31 2 32 2 3 Output 3 ...
- excel——VlookUp函数的使用
VlookUp函数,查询两个表中的相同字段数据,并将需要引用的数据从B表填充到A表 1.打开A表,将需要查询的列选中 在需要引用的列输入 = 在上方,函数选择中选择VLOOKUP函数 Windows: ...
- 轻轻松松学CSS:Grid布局
网页布局总的来说经历了以下四个阶段: 1.古老的table表格布局,现在基本已被淘汰. 2.float浮动布局(或者position定位布局),借助float.position 等属性等进行布局,这种 ...
- Java源码详解系列(十一)--Spring的使用和源码
Spring 是一个一站式的 Java 框架,致力于提高我们项目开发的效率.通过 Spring,我们可以避免编写大量额外代码,更专注于我们的核心逻辑.目前,Spring 已经成为最受欢迎的 Java ...
- dockerfile-maven-plugin极简教程
目录 一.简介 二.概述 三.将spring-boot-app打包成docker镜像 创建示例应用 修改pom文件 增加Dockerfile文件 使用Maven打包应用 运行应用镜像 四.分析mvn ...
- kubernetes-介绍与特性
1. kubernetes概述 1) kubernetes是什么 2) kubernetes能做什么 3) kubernetes特性 4) kubernetes集群架构与组件 5) kubernete ...
- ps 安装 ps 2017 下载 及教程(保姆式教程)
链接:https://pan.baidu.com/s/1GJHiwmxwRApFYhyNZBCQtQ 提取码:7r6u 以上是百度网盘的地址. 1.下载解压安装前先断网在安装点击set-up 软件,之 ...