I am working on visual studio 2012 and trying to use several threads on a very simple hello word example :
#include <omp.h>
#include <stdio.h>
int main() {
omp_set_dynamic(0);
omp_set_num_threads(4);
#pragma omp parallel
printf("Hello from thread %d, nthreads %d\n", omp_get_thread_num(), omp_get_num_threads());
}
But the result I got is :
Hello from thread 0, nthreads 1
Why can't I have 4 threads ?
Related
So I have a task. I need to make 8 threads an make them write their numbers in reverse order. I know how to make them write in natural order, but really confused about the reverse one. Hope anyone can help me!
I don't really understand the purpose of what you are asking but this works
#include "omp.h"
#include <iostream>
using namespace std;
int main()
{
#pragma omp parallel
{
int nthreads = omp_get_num_threads();
for(int i=nthreads-1; i>=0; i--)
{
#pragma omp barrier
{
if(i==omp_get_thread_num())
{
#pragma omp critical
cout << "I am thread "<< i <<endl;
}
}
}
}
}
8 threads it outputs
I am thread 7
I am thread 6
I am thread 5
I am thread 4
I am thread 3
I am thread 2
I am thread 1
I am thread 0
#include<omp.h>
#include<stdio.h>
#include<stdlib.h>
void main(int argc, int *argv[]){
#pragma omp parallel num_threads(3)
{
int tid = omp_get_thread_num();
printf("Hello world from thread = %d \n",tid);
if(tid == 0){
int nthreads = omp_get_num_threads();
printf("Number of threads = %d\n",nthreads);
}
}
}
I am learning OpenMP and I don't understand why it executes only one thread when I have specified the number of threads 3?
The program ouptut:
Hello world from thread = 0
Number of threads = 1
You need to compile your program with -fopenmp.
g++ a.cc -fopenmp
In VisualStudio just switch on OMP. You can refer to https://msdn.microsoft.com/de-de/library/fw509c3b(v=vs.120).aspx
omp_get_num_threads() returns the total number of threads being used
omp_get_thread_num() returns the current thread ID
You should use the former one
I am trying to learn OMP library task based programming and as an example I copied and pasted the code below taken from a book and it outputs errors
'task' : expected an OpenMP directive name
and
'taskwait' : expected an OpenMP directive name
I can run omp parallel for loops but not tasks. Do you know whether omp tasking needs any further adjustments in visual studio?
#include "stdafx.h"
#include <omp.h>
int fib(int n)
{
int i, j;
if (n<2)
return n;
else
{
#pragma omp task shared(i) firstprivate(n)
i=fib(n-1);
#pragma omp task shared(j) firstprivate(n)
j=fib(n-2);
#pragma omp taskwait
return i+j;
}
}
int main()
{
int n = 10;
omp_set_dynamic(0);
omp_set_num_threads(4);
#pragma omp parallel shared(n)
{
#pragma omp single
printf ("fib(%d) = %d\n", n, fib(n));
}
}
Unfortunately, even Visual Studio 2019 still only supports OpenMP 2.0, while Tasks were an OpenMP 3.0 addition and the current standard at the time of writing is 5.0.
this is an exercise from the OpenMP website:
https://computing.llnl.gov/tutorials/openMP/exercise.html
#include "stdafx.h"
#include <omp.h>
#include <stdio.h>
#include <stdlib.h>
int _tmain(int argc, _TCHAR* argv[])
{
int nthreads, i, tid;
float total;
/*** Spawn parallel region ***/
#pragma omp parallel private(i, tid) // i changed this line
{
/* Obtain thread number */
tid = omp_get_thread_num();
/* Only master thread does this */
if (tid == 0) {
nthreads = omp_get_num_threads();
printf("Number of threads = %d\n", nthreads);
}
printf("Thread %d is starting...\n",tid);
#pragma omp barrier
/* do some work */
total = 0.0;
#pragma omp for schedule(dynamic,10)
for (i=0; i<1000000; i++)
total = total + i*1.0;
printf ("Thread %d is done! Total= %e\n",tid,total);
}
}
the output for this is
Number of threads = 4
Thread 0 is starting...
Thread 3 is starting...
Thread 2 is starting...
Thread 1 is starting...
Thread 0 is done! Total= 0.000000e+000
Thread 3 is done! Total= 0.000000e+000
Thread 2 is done! Total= 0.000000e+000
Thread 1 is done! Total= 0.000000e+000
which means we have a problem with the variable "total"
this is the help on the site
Here is my Solution: do you think this is the correct way to do it?
#include "stdafx.h"
#include <omp.h>
#include <stdio.h>
#include <stdlib.h>
int _tmain(int argc, _TCHAR* argv[])
{
int nthreads, i, tid;
float total;
/*** Spawn parallel region ***/
#pragma omp parallel private(total,tid)
{
/* Obtain thread number */
tid = omp_get_thread_num();
total= 0.0;
/* Only master thread does this */
if (tid == 0) {
nthreads = omp_get_num_threads();
printf("Number of threads = %d\n", nthreads);
}
printf("Thread %d is starting...\n",tid);
#pragma omp parallel for schedule(static,10)\
private(i)\
reduction(+:total)
for (i=0; i<1000000; i++)
total = total + i*1.0;
printf ("Thread %d is done! Total= %e\n",tid,total);
} /*** End of parallel region ***/
}
Here is my new output:
Number of threads = 4
Thread 0 is starting...
Thread 1 is starting...
Thread 0 is done! Total= 4.999404e+011
Thread 2 is starting...
Thread 1 is done! Total= 4.999404e+011
Thread 2 is done! Total= 4.999404e+011
Thread 3 is starting...
Thread 3 is done! Total= 4.999404e+011
Yes you certainly want total to be a thread-private variable. One thing you presumably would do in a real example is to reduce the thread-private totals to a single global total at the end (and only let one thread print the result then). One way to do that is a simple
#pragma omp atomic
global_total += total
at the end (there are better ways though using reductions).
PS: Loop counters for omp for are by default private, so you actually don't have to explicitly specify that.
I have a following parallel snippet:
#include <omp.h>
#include "stdio.h"
int main()
{
omp_set_num_threads(4);
int i;
#pragma omp parallel private(i)
{
#pragma omp for
for(i = 0;i < 10; i++) {
printf("A %d: %d\n", omp_get_thread_num(),i);
}
#pragma omp critical
printf("i %d: %d\n", omp_get_thread_num(), i );
}
}
I thought that after the loop, each thread will have i equal to i last value in the thread's loop. My desired output would be:
A 0: 0
A 0: 1
A 0: 2
A 3: 9
A 2: 6
A 2: 7
A 2: 8
A 1: 3
A 1: 4
A 1: 5
i 0: 3
i 3: 10
i 2: 9
i 1: 6
whereas what I get is:
A 0: 0
A 0: 1
A 0: 2
A 3: 9
A 2: 6
A 2: 7
A 2: 8
A 1: 3
A 1: 4
A 1: 5
i 0: -1217085452
i 3: -1217085452
i 2: -1217085452
i 1: -1217085452
How to make i to hold last iteration's value? lastprivate(i) makes i = 10 for all threads, and that is not what I want.
It turns out you can't. OpenMP alters program semantics.
Parallel for loops are rewritten by the compiler according to well-defined set of rules.
This also implies you cannot break from, return from such a loop. You can also not directly manipulate the loop variable. The loop condition can not call random functions or do any conditional expression, in short: a omp parallel for loop is not a for loop
#include <omp.h>
#include "stdio.h"
int main()
{
omp_set_num_threads(4);
#pragma omp parallel
{
int i;
#pragma omp for
for(i = 0;i < 10; i++) {
printf("A %d: %d\n", omp_get_thread_num(),i);
}
#pragma omp critical
printf("i %d: %d\n", omp_get_thread_num(), i );
}
}
Thanks to sehe`s post, I figure out the following dirty trick that solves the problem
int i, last_i;
#pragma omp parallel private(i)
{
#pragma omp for
for(i = 0;i < 10; i++) {
printf("A %d: %d\n", omp_get_thread_num(),i);
last_i = i;
}
#pragma omp critical
printf("i %d: %d\n", omp_get_thread_num(), last_i );
}
}