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************* ...
随机推荐
- 深入理解TypeScript——第一章:上手篇
怎么定义TypeScript呢? TypeScript是一个工具 是一个编译器 编译代码 TypeScript,通过它的能力,默认使用tsc命令,可以根据.ts为后缀名的文件生成一个新的js文件 2. ...
- mybatis进行mapper.xml测试的时候发生"必须为元素类型 “mapper” 声明属性 “namespace”
1.Caused by Caused by: org.xml.sax.SAXParseException; lineNumber: 7; columnNumber: 45; 必须为元素类型 " ...
- 对抗生成网络 Generative Adversarial Networks
1. Basic idea 基本任务:要得到一个generator,能够模拟想要的数据分布.(一个低维向量到一个高维向量的映射) discriminator就像是一个score function. 如 ...
- 完全小白入门:python的下载和安装
1. 打开官网www.python.org,选择Downloads
- Black-Lives-Matter-Resources
下载 Black-Lives-Matter-ResourcesBlack-Lives-Matter-Resources 关于最近在美国发生的事件的资源列表 链接 描述 由于(可选) 插入链接 在这里插 ...
- Docker Stack 笔记
Docker Compose (Docker Stack) image: Specify the image to start the container from. Can either be a ...
- 【迷宫问题】CodeForces 1292A A NEKO's Maze Game
题目大意 vjudge链接 共两行,从(1,n)到(2,n). 每过一个时刻会有一个位置的状态变化,从能到达这个位置变成不能到达,或从不能到达变成能到达,问在每个时刻中是否能从起点到终点. 数据范围 ...
- 高度集成智能家居物联网网关WiFi通信应用的无线路由模块:模小块成长记
大家好,我叫模小块,代号L107模块,出生在BOJINGnet大家庭里,我在物联网网关里不可或缺,或许业内专业人士和物联网工程师知道我的存在.别看我体积小(40mm25mm3mm),贴片式邮票孔接口( ...
- linux学习(一)--启动文件bootsect.s
这是linux由BIOS加载后执行的第一段的启动程序代码,即文件 boot/bootsect.s 首先附图,简单介绍一下从开机加电到第一段linux代码执行的简要过程 1 .globl begte ...
- ansible2.9.5使用become参数实现sudo功能
一,为什么要使用sudo? 1, 生产环境中,为了安全因素,我们不会直接使用root来登录到server, 确实有需要的情况下,我们再使用sudo切换到root权限. 所以很多ansible的演示直接 ...