Tag: openmp

使用OpenMP并行循环

我有一个非常大的数据文件,该数据文件中的每条记录有4行。 我编写了一个非常简单的C程序来分析这种类型的文件并打印出一些有用的信息。 该计划的基本理念是这样的。 int main() { char buffer[BUFFER_SIZE]; while(fgets(buffer, BUFFER_SIZE, stdin)) { fgets(buffer, BUFFER_SIZE, stdin); do_some_simple_processing_on_the_second_line_of_the_record(buffer); fgets(buffer, BUFFER_SIZE, stdin); fgets(buffer, BUFFER_SIZE, stdin); } print_out_result(); } 这当然会遗漏一些细节(健全/错误检查等),但这与问题无关。 该程序工作正常,但我正在使用的数据文件是巨大的。 我想我会尝试通过使用OpenMP并行化循环来加速程序。 但是,经过一些搜索后,OpenMP似乎只能处理事先知道迭代次数的循环。 由于我事先并不知道文件的大小,甚至像wc -l这样的简单命令需要很长时间才能运行,我该如何并行化这个程序呢?

C语言中OpenMP中静态和动态调度的区别

我有两个类似的代码。 第一 #pragma omp parallel for shared(g) private(i) schedule(dynamic, 1) for(i = (*g).actualNumberOfChromosomes; i < (*g).maxNumberOfChromosomes; i++) { AddCrossoverChromosome(g, i); // it doesnt change actualNumberOfChromosomes #pragma omp atomic (*g).actualNumberOfChromosomes++; } 第二 #pragma omp parallel for shared(g) private(i) schedule(static, 1) for(i = (*g).actualNumberOfChromosomes; i < (*g).maxNumberOfChromosomes; i++) { AddCrossoverChromosome(g, i); // it doesnt change actualNumberOfChromosomes #pragma […]

OpenMP特定线程数急剧减速

我运行了一个OpenMP程序来执行Jacobi方法,它运行得非常好,2个线程执行略超过2x 1线程,4个线程比1个线程快2倍。 我觉得一切都很完美……直到我准确地达到了20,22和24个线程。 我一直把它分解,直到我有这个简单的程序 #include #include int main(int argc, char *argv[]) { int i, n, maxiter, threads, nsquared, execs = 0; double begin, end; if (argc != 4) { printf(“4 args\n”); return 1; } n = atoi(argv[1]); threads = atoi(argv[2]); maxiter = atoi(argv[3]); omp_set_num_threads(threads); nsquared = n * n; begin = omp_get_wtime(); while (execs < […]

使用OpenMP-Tasks的生产者 – 消费者

我正在尝试使用OpenMP中的任务实现并行算法。 并行编程模式基于生产者 – 消费者的想法,但由于消费者流程比生产者慢,我想使用一些生产者和几个消费者。 主要思想是创建与生产者一样多的OS线程,然后每个线程创建要并行完成的任务(由消费者完成)。 每个生产者都将与相应数量的消费者(即numCheckers / numSeekers)相关联。 我在英特尔双芯片服务器上运行该算法,每个芯片有6个内核。 问题在于,当我只使用一个生产者(寻求者)和越来越多的消费者(检查员)时,随着消费者数量的增长,性能衰退得很快(见下表),即使正确的核心数量在100%。 另一方面,如果我增加生产者的数量,平均时间减少或至少保持稳定,即使消费者数量成比例。 在我看来,所有的改进都是通过生产者之间的输入划分来实现的,而且任务只是烦恼。 但同样,我对一个生产者的行为没有任何解释。 我在OpenMP-Task逻辑中遗漏了什么? 难道我做错了什么? ————————————————————————- | producers | consumers | time | ————————————————————————- | 1 | 1 | 0.642935 | | 1 | 2 | 3.004023 | | 1 | 3 | 5.332524 | | 1 | 4 | 7.222009 | | 1 | […]

为什么这段代码不能线性扩展?

我写了这个SOR求解器代码。 不要太费心这个算法做什么,这不是关注点。 但仅仅为了完整性:它可以解决线性方程组,这取决于系统的条件有多好。 我用一个病态的2097152行sparce矩阵(从不收敛)运行它,每行最多7个非零列。 翻译:外部do-while循环将执行10000次迭代(我传递的值为max_iters ),中间将执行2097152次迭代,拆分为work_line块,在OpenMP线程之间划分。 最里面的for循环将有7次迭代,除非极少数情况下(小于1%)它可以更少。 sol数组中的线程之间存在数据依赖性。 中间的每次迭代都会更新一个元素,但最多可读取数组的其他6个元素。 由于SOR不是一个精确的算法,在读取时,它可以具有该位置上的任何先前值或当前值(如果您熟悉求解器,这是一个Gauss-Siedel,在某些地方容忍Jacobi行为,为了并行)。 typedef struct{ size_t size; unsigned int *col_buffer; unsigned int *row_jumper; real *elements; } Mat; int work_line; // Assumes there are no null elements on main diagonal unsigned int solve(const Mat* matrix, const real *rhs, real *sol, real sor_omega, unsigned int max_iters, real tolerance) { real […]

使用omp_set_num_threads()设置线程数为2,但是omp_get_num_threads()返回1

我有使用OpenMP的以下C / C ++代码: int nProcessors=omp_get_max_threads(); if(argv[4]!=NULL){ printf(“argv[4]: %s\n”,argv[4]); nProcessors=atoi(argv[4]); printf(“nProcessors: %d\n”,nProcessors); } omp_set_num_threads(nProcessors); printf(“omp_get_num_threads(): %d\n”,omp_get_num_threads()); exit(0); 如您所见,我正在尝试根据命令行传递的参数设置要使用的处理器数量。 但是,我得到以下输出: argv[4]: 2 //OK nProcessors: 2 //OK omp_get_num_threads(): 1 //WTF?! 为什么omp_get_num_threads()返回2?!!! 正如已经指出的那样,我在串行区域中调用omp_get_num_threads() ,因此函数返回1 。 但是,我有以下并行代码: #pragma omp parallel for private(i,j,tid,_hash) firstprivate(firstTime) reduction(+:nChunksDetected) for(i=0;i<fileLen-CHUNKSIZE;i++){ tid=omp_get_thread_num(); printf("%d\n",tid); int nThreads=omp_get_num_threads(); printf("%d\n",nThreads); … 哪个输出: 0 //tid 1 //nThreads – this should […]

指定OpenMP到GCC

对于OpenMP,当我的代码使用其API中的函数(例如,omp_get_thread_num())而不使用其指令(例如#pragma omp …)时, 为什么直接将libgomp.a指定为gcc而不是使用-fopenmp不起作用,例如 gcc hello.c /usr/lib/gcc/i686-linux-gnu/4.4/libgomp.a -o hello 更新:我刚刚发现链接到libgomp.a不起作用,但链接到libgomp.so工作。 这是否意味着OpenMP不能静态链接? 为什么-fopenmp只能在不指定库文件的情况下工作 gcc hello.c -fopenmp -o hello 更新:换句话说,当使用-fopenmp时,为什么不需要显式链接到libgomp.so? 为什么这也编译: gcc hello.c -L/usr/lib/gcc/i686-linux-gnu/4.4/ -lgomp -o hello 如果有的话,这会忽略代码中的OpenMP指令吗? 感谢致敬!

在没有它的机器上忽略OpenMP

我有一个使用OpenMP的C ++程序,它将运行在可能安装或未安装OpenMP的几台机器上。 如果机器没有OpenMP并忽略那些#include ,OpenMP指令(如#pragma omp parallel … )和/或库函数(如tid = omp_get_thread_num(); ),我怎么能知道我的程序#pragma omp parallel … ?

OpenMP – 为什么比较次数会减少?

我有以下算法: int hostMatch(long *comparisons) { int i = -1; int lastI = textLength-patternLength; *comparisons=0; #pragma omp parallel for schedule(static, 1) num_threads(1) for (int k = 0; k <= lastI; k++) { int j; for (j = 0; j i) i = k; } return i; } 更改num_threads我得到以下比较数的结果: 01 = 9949051000 02 = 4992868032 04 = […]

OpenMP比1个线程慢于顺序版本

我使用OpenMP(gcc版本4.6.3)实现了背包 #define MAX(x,y) ((x)>(y) ? (x) : (y)) #define table(i,j) table[(i)*(C+1)+(j)] for(i=1; i<=N; ++i) { #pragma omp parallel for for(j=1; jj) { table(i,j) = table(i-1,j); }else { table(i,j) = MAX(profits[i]+table(i-1,j-weights[i]), table(i-1,j)); } } } 顺序程序的执行时间= 1s openmp的执行时间为1个线程= 1.7s(开销= 40%) 在这两种情况下使用相同的编译器优化标志(-O3)。 有人可以解释这种行为背后的原因。 谢谢。