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. Metasploit之令牌窃取

    令牌简介及原理 令牌(Token) 就是系统的临时密钥,相当于账户名和密码,用来决定是否允) 许这次请求和判断这次请求是属于哪一个用户的.它允许你在不提供密码或其他凭证的前提下,访问网络和系统资源.这 ...

  2. SpringBoot中pom引入gson异常

    在pom中引入gson依赖,启动spring boot项目中报错 Description:An attempt was made to call the method com.google.gson. ...

  3. 简化ETL工作,编写一个Canal胶水层

    前提 这是一篇憋了很久的文章,一直想写,却又一直忘记了写.整篇文章可能会有点流水账,相对详细地介绍怎么写一个小型的"框架".这个精悍的胶水层已经在生产环境服役超过半年,这里尝试把耦 ...

  4. 【题解】「MCOI-02」Convex Hull 凸包

    题目戳我 \(\text{Solution:}\) \[\sum_{i=1}^n \sum_{j=1}^n \rho(i)\rho(j)\rho(\gcd(i,j)) \] \[=\sum_{d=1} ...

  5. P4107 [HEOI2015]兔子与樱花 贪心

    题目描述 传送门 分析 一道贪心题 首先我们可以证明最优的贡献一定是从下依次合并到上的 不会出现一个节点不能合并到父亲节点,却能合并到父亲节点的祖先节点的情况 我们设当前的节点为 \(u\),\(u\ ...

  6. The comparison between object and constructor

    1.相似的地方 1.举个栗子:public struct Student{    string name;    int age;}public class bike{    int weight;  ...

  7. 多测师讲解python _函数return_高级讲师肖sir

    # 函数中的返回的作用: 注意点:(1)调用函数===没有加print 调用函数为空,加了print调用函数打印输出none              (2)在函数中碰到return语句赋值直接返回r ...

  8. ansible2.4安装和体验

    欢迎访问我的GitHub https://github.com/zq2599/blog_demos 内容:所有原创文章分类汇总及配套源码,涉及Java.Docker.Kubernetes.DevOPS ...

  9. ssh登录二次验证,让服务器更安全。

    码云地址 sshdTwoVerification 介绍 ssh登录二次验证 问题:现在很多人的Linux服务器可能会被攻击,只校验一次后台用户名密码登录变得不再保险. 当然大家首先要做的是修改ssh服 ...

  10. logstash-配置文件详解

      kafka  将 kafka topic 中的数据读取为事件   kafka{ bootstrap_servers=> "kafka01:9092,kafka02:9092,kaf ...