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的更多相关文章

  1. Introduction to Parallel Computing

    Copied From:https://computing.llnl.gov/tutorials/parallel_comp/ Author: Blaise Barney, Lawrence Live ...

  2. openmp 的使用

    http://blog.csdn.net/gengshenghong/article/details/7003110 说明:这部分内容比较基础,主要是分析几个容易混淆的OpenMP函数,加以理解. ( ...

  3. 并行计算之OpenMP入门简介

    在上一篇文章中介绍了并行计算的基础概念,也顺便介绍了OpenMP. OpenMp提供了对于并行描述的高层抽象,降低了并行编程的难度和复杂度,这样程序员可以把更多的精力投入到并行算法本身,而非其具体实现 ...

  4. OpenMP并行程序设计

    1.fork/join并行执行模式的概念 2.OpenMP指令和库函数介绍 3.parallel 指令的用法 4.for指令的使用方法 5 sections和section指令的用法 1.fork/j ...

  5. 通过 GCC 学习 OpenMP 框架

     OpenMP 框架是使用 C.C++ 和 Fortran 进行并发编程的一种强大方法.GNU Compiler Collection (GCC) V4.4.7 支持 OpenMP 3.0 标准,而 ...

  6. [转]OpenMP中几个容易混淆的函数(线程数量/线程ID/线程最大数)以及并行区域线程数量的确定

    说明:这部分内容比较基础,主要是分析几个容易混淆的OpenMP函数,加以理解. (1)并行区域数量的确定: 在这里,先回顾一下OpenMP的parallel并行区域线程数量的确定,对于一个并行区域,有 ...

  7. [转载]John Burkardt搜集的FORTRAN源代码

    Over the years, I have collected, modified, adapted, adopted or created a number of software package ...

  8. 竞态条件 race condition data race

    竞态条件 race condition Race condition - Wikipedia https://en.wikipedia.org/wiki/Race_condition A race c ...

  9. Fortran并行计算的一些例子

    以下例子来自https://computing.llnl.gov/tutorials/openMP/exercise.html网站 一.打印线程(Hello world) C************* ...

随机推荐

  1. python类中的__init__和__new__方法

    Python中类: Python中在创建类的过程中最先调用的不是__init__方法而是__new__方法,__new__方法是一个静态方法,在创建一个类对象时其实是通过__new__方法首先创建出一 ...

  2. 文件上传限制条件(JS、后缀、文件名、类型、截断)绕过及修复建议

    在现代互联网的Web应用程序中,上传文件是一 种常见的功能,因为它有助于提高业务效率,比如企业的OA系统,允许用户上传图片.视频.头像和许多其他类型的文件.然而向用户提供的功能越多,Web应用受到攻击 ...

  3. Kafka日志段读写分析

    引子 之所以写这篇文章是因为之前面试时候被面试官问到(倒)了,面试官说:"你说你对Kafka比较熟?看过源码? 那说说kafka日志段如何读写的吧?" 我心里默默的说了句 &quo ...

  4. 主键生成器效率提升方案|基于雪花算法和Redis控制进程隔离

    背景 主键生成效率用数据库自增效率也是比较高的,为什么要用主键生成器呢?是因为需要insert主表和明细表时,明细表有个字段是主表的主键作为关联.所以就需要先生成主键填好主表明细表的信息后再一次过在一 ...

  5. VueCroppie

    下载 VueCroppie VueCroppie是一个Vue 2包装Croppie一个美丽的照片裁剪工具的Javascript由foliotek. 安装 NPM 安装vue-croppie-保存 CD ...

  6. 「Redis」字符串

    原文链接:https://www.changxuan.top/?p=1109 简介 Redis 中自定义的字符串结构. 字符串是 Redis 中最常用的一种数据类型,在 Redis 中专门封装了一个字 ...

  7. Oracle 正确删除归档日志的方法

    我们都知道在controlfile中记录着每一个archivelog文件的相关信息,当然们在OS下把这些物理文件delete掉后,在我们的controlfile中仍然记录着这些archivelog文件 ...

  8. 如何快速构建React组件库

    前言 俗话说:"麻雀虽小,五脏俱全",搭建一个组件库,知之非难,行之不易,涉及到的技术方方面面,犹如海面风平浪静,实则暗礁险滩,处处惊险- 目前团队内已经有较为成熟的 Vue 技术 ...

  9. IOS使用UITextView进行富文本编辑|纯干货

    看了好多blog介绍富文本编辑,有很多很好的开源项目,比如:YYText.FastTextView.ZSSRichTextEditor等等.本着学习的目的还是选择用UITextView来实现简单的富文 ...

  10. chrome(谷歌)登录失败解决方案

    相信有很多小伙伴和我一样,同步chrome的收藏夹,这样也便于随时可以查看自己收藏的网址.但是同步文件,必须先要登录chrome账号,登录chrome账号时,总是会报黄页,或者一直加载不出来.接下来, ...