在C++ 11中,有许多新的随机数生成器引擎和分发函数.它们是否安全?如果您在多个线程之间共享一个随机分布和引擎,它是否安全并且您是否仍会收到随机数?我正在寻找的场景是这样的,
void foo() {
std::mt19937_64 engine(static_cast<uint64_t> (system_clock::to_time_t(system_clock::now())));
std::uniform_real_distribution<double> zeroToOne(0.0, 1.0);
#pragma omp parallel for
for (int i = 0; i < 1000; i++) {
double a = zeroToOne(engine);
}
}
Run Code Online (Sandbox Code Playgroud)
使用OpenMP或
void foo() {
std::mt19937_64 engine(static_cast<uint64_t> (system_clock::to_time_t(system_clock::now())));
std::uniform_real_distribution<double> zeroToOne(0.0, 1.0);
dispatch_apply(1000, dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0), ^(size_t i) {
double a = zeroToOne(engine);
});
}
Run Code Online (Sandbox Code Playgroud)
使用libdispatch.
以下代码是仅仅并行化第一个(外部)循环,还是并行化整个嵌套循环?
#pragma omp parallel for
for (int i=0;i<N;i++)
{
for (int j=0;j<M;j++)
{
//do task(i,j)//
}
}
Run Code Online (Sandbox Code Playgroud)
我只是想确定上面的代码是否会并行化整个嵌套的for循环(因此一个线程直接相关的任务(i,j)),或者它只是并行化外部for循环(因此它确保了每个并行)带有循环索引i的线程,它的内部循环将在一个线程中顺序完成,这非常重要).
我想了解的确切差异#pragma omp critical和#pragma omp singleOpenMP中:
微软的定义是:
所以这意味着在两者中,之后的代码的确切部分将仅由一个线程执行而其他线程将不会进入该部分,例如,如果我们打印某些内容,我们将在屏幕上看到一次结果,对吧?
差异怎么样?它看起来很重要,可以处理执行时间,但不是单一的!但是我没有看到练习中的任何差异!这是否意味着其他线程(不进入该部分)的某种等待或同步被认为是关键的,但没有什么能够将其他线程保持在单一状态?它如何改变实践中的结果?
我很感激,如果有人能够通过一个例子向我澄清这一点.谢谢!
我想知道如何检查Linux远程机器上的OpenMP版本?
我也不知道它的安装位置.
我有一个使用OpenMP的C++程序,它将运行在可能安装或未安装OpenMP的几台机器上.
如果机器没有OpenMP并忽略那些#include <omp.h>,OpenMP指令(如#pragma omp parallel ...)和/或库函数(如tid = omp_get_thread_num();),我怎么能知道我的程序?
我有一个C扩展,我想使用OpenMP.但是,当我导入我的模块时,出现导入错误:
ImportError: /home/.../_entropysplit.so: undefined symbol: GOMP_parallel_end
Run Code Online (Sandbox Code Playgroud)
我用-fopenmp和-lgomp编译了模块.这是因为我的Python安装没有用-fopenmp标志编译吗?我是否必须从源代码构建Python?还是有其他可能性吗?这是我在模块中实际使用openmp的唯一时间:
unsigned int feature_index;
#pragma omp parallel for
for (feature_index = 0; feature_index < num_features; feature_index++) {
Run Code Online (Sandbox Code Playgroud)
如果可能的话,我想坚持使用openmp,因为它非常简单,并且在这种情况下并行化非常适合它.
编辑:我咬了一口气,用OpenMP支持重新编译了Python.我的模块现在完美运行,但这不是一个很好的解决方案.如果需要完全重新编译Python,我无法真正分发它.所以有人知道这方面的一些方法吗?或许ctypes会起作用吗?
解决了!这是一个简单的链接问题.(我为此重建了Python?!)在编译模块期间,OpenMP没有正确链接.因此,IS可以加载使用OpenMP的一个C Python扩展.
我试图让openmp在我的程序中运行Mavericks,但是当我尝试使用标志进行编译时,-fopenmp我得到以下错误:
ld: library not found for -lgomp
clang: error: linker command failed with exit code 1 (use -v to see invocation)
Run Code Online (Sandbox Code Playgroud)
我正在运行的命令是:
gcc myProgram.cpp -fopenmp -o myProgram
Run Code Online (Sandbox Code Playgroud)
此外,当我运行gcc时,我得到了Clang警告,我觉得这很奇怪.并且查看/ usr/bin/gcc它似乎没有链接到Clang.
有关如何修复我的Clang错误并获得openmp编译的任何建议?
UPDATE
不幸的是,由于我的疏忽,我有一个旧版本的MKL(11.1)链接到numpy.较新版本的MKL(11.3.1)在C中和从python调用时具有相同的性能.
什么是模糊的东西,即使将编译的共享库与新的MKL明确地链接,并将LD_*变量指向它们,然后在python中执行import numpy,以某种方式使python调用旧的MKL库.只有在python lib文件夹中替换所有libmkl _*.所以使用更新的MKL我能够匹配python和C调用中的性能.
背景/图书馆信息.
矩阵乘法是通过numpy.dot函数通过sgemm(单精度)和dgemm(双精度)Intel的MKL库调用完成的.可以使用例如oprof来验证库函数的实际调用.
在这里使用2x18核心CPU E5-2699 v3,因此共有36个物理核心.KMP_AFFINITY =散射.在linux上运行.
TL; DR
1)为什么numpy.dot,即使它调用相同的MKL库函数,与C编译代码相比,最好慢两倍?
2)为什么通过numpy.dot随着内核数量的增加而性能下降,而在C代码中没有观察到相同的效果(调用相同的库函数).
问题
我观察到在numpy.dot中进行单/双精度浮点矩阵乘法,以及直接从编译的C 共享库调用cblas_sgemm/dgemm,与从纯C内部调用相同的MKL cblas_sgemm/dgemm函数相比,性能明显更差码.
import numpy as np
import mkl
n = 10000
A = np.random.randn(n,n).astype('float32')
B = np.random.randn(n,n).astype('float32')
C = np.zeros((n,n)).astype('float32')
mkl.set_num_threads(3); %time np.dot(A, B, out=C)
11.5 seconds
mkl.set_num_threads(6); %time np.dot(A, B, out=C)
6 seconds
mkl.set_num_threads(12); %time np.dot(A, B, out=C)
3 seconds
mkl.set_num_threads(18); %time np.dot(A, B, out=C)
2.4 seconds
mkl.set_num_threads(24); %time np.dot(A, B, out=C)
3.6 seconds
mkl.set_num_threads(30); %time np.dot(A, B, out=C)
5 …Run Code Online (Sandbox Code Playgroud) 我正在使用C++中的OpenMP编写并行程序.
我想控制程序中使用的线程数omp_set_num_threads(),但它不起作用.
#include <iostream>
#include <omp.h>
#include "mpi.h"
using namespace std;
int myrank;
int groupsize;
double sum;
double t1,t2;
int n = 10000000;
int main(int argc, char *argv[])
{
MPI_Init( &argc, &argv);
MPI_Comm_rank( MPI_COMM_WORLD, &myrank );
MPI_Comm_size(MPI_COMM_WORLD,&groupsize);
omp_set_num_threads(4);
sum = 0;
#pragma omp for reduction(+:sum)
for (int i = 0; i < n; i++)
sum+= i/(n/10);
cout<<"sum="<<sum<<endl;
cout<<"threads="<<omp_get_num_threads()<<endl;
MPI_Finalize();
return 0;
}
Run Code Online (Sandbox Code Playgroud)
该方案产出:
sum = 4.5e+007
threads=1
Run Code Online (Sandbox Code Playgroud)
如何控制线程数?