
Библиотечные функции OpenMp
Использование библиотеки
Для вызова библиотечных функций в программе надо подключить
соответствующий заголовочный файл:
#include <omp.h>
Функция, используемая для замера времени:
double omp_get_wtime(void);
Определение точности измерения времени:
double omp_get_wtick(void);
Задание количества потоков:
void omp_set_num_threads(int num);
Задан ли флаг возможности динамического изменения количества
выполняющихся потоков:
int omp_get_dynamic(void);
Установка динамического флага (0 или 1):
void omp_set_dynamic(int num);
Определение максимального количества потоков:
int omp_get_max_threads(void);
Находится ли точка вызова в параллельной области:
int omp_in_parallel(void);
Определение номера потока:
int omp_get_thread_num(void);
Определение количества выполняющихся потоков:
int omp_get_num_threads(void);
makefile
CC = gcc
CFLAGS = -fopenmp -c
LFLAGS = -lm -lgomp
redtest: redtest.o
\ $(CC) -o redtest redtest.o $(LFLAGS)
redtest.o: redtest.c
\ $(CC) $(CFLAGS) redtest.c
Пример использования редукции
#include <stdio.h>
int main(int argc, char *argv[])
{
int count = 0;
#pragma omp parallel reduction (+: count)
{
count++;
printf("Текущее значение count: %d\n", count);
}
printf("Число нитей: %d\n", count);
}
Директива параллельного цикла
Директива относится только к циклу, непосредственно следующему за ней:
#pragma omp parallel
{
...
#pragma omp for [опции]
for(...)
{
}
...
}
Если в параллельной области есть только один блок — сам цикл, тогда
директива может использовать сокращенную форму:
#pragma omp parallel for [опции]
for(...)
{
}
Пример использование параллельного цикла
#include <stdio.h>
#include <omp.h>
int main(int argc, char *argv[])
{
int A[10], B[10], C[10], i, n;
/* Заполним исходные массивы */
for (i=0; i<10; i++){ A[i]=i; B[i]=2*i; C[i]=0; }
#pragma omp parallel shared(A, B, C) private(i, n)
{
/* Получим номер текущей нити */
n=omp_get_thread_num();
#pragma omp for
for (i=0; i<10; i++)
{
C[i]=A[i]+B[i];
printf("Нить %d сложила элементы с номером %d\n",n, i);
}
}
}
Директива sections
Директива sections используется для назначения каждому потоку своей
задачи:
#pragma omp parallel sections
{
#pragma omp section
{
// код первой ветви
dosmth1();
}
#pragma omp section
{
// код второй ветви
dosmth2();
}
}
Барьер:
#pragma omp barrier
Критическая секция:
#pragma omp critical [(<имя критической секции>)]
Пример использования критической секции:
#include <stdio.h>
#include <omp.h>
int main(int argc, char *argv[])
{
int n;
#pragma omp parallel
{
#pragma omp critical
{
n=omp_get_thread_num();
printf("Нить %d\n", n);
}
}
}