| Украина, г. Киев |
Опубликован: 11.10.2012 | Уровень: для всех | Доступ: платный | ВУЗ: Санкт-Петербургский государственный университет
Лекция 1:
Обзор средств разработки высокопроизводительных приложений
POSIX Threads
Стандарт POSIX реализации потоков (нитей) выполнения, определяющий API для создания и управления ими.
POSIX.1c, Расширения потоков (IEEE Std 1003.1c-1995)
- Создание, управление и завершение выполнения потоков
- Планировщик потоков
- Синхронизация потоков
- Обработка сигналов
Реализации стандарта содержат:
- функции управления потоками
- функции синхронизации потоков
POSIX Threads. Пример
#include <stdio.h>
#include "gettimeofday.h"
#include <pthread.h>
#define gNumThreads 1
#define N 100000000
double a[N + 1], b[N + 1], sum;
int i, j;
double start, stop;
const int gNumSteps = N;
double gVectorSum = 0;
void *threadFunction(void *arg)
{
int i;
int myNum = *((int *)arg);
double partialSum = 0; // локально по отношению к каждому потоку
for ( i = myNum; i < gNumSteps; i += gNumThreads ) // каждый gNumThreads-й шаг
{
partialSum += a[i] * b[i]; // параллельное вычисление сумм каждым потоком
}
gVectorSum += partialSum; // сложения частных сумм и получение результата
return 0;
}
int main()
{
pthread_t tid[gNumThreads];
int tNum[gNumThreads], i, j;
// инициализация вектора
for (j = 0; j < N; j++)
{
a[j] = 1.031; b[j] = 1.057;
}
printf("Computed value of vector sum: ");
start = wcgettimeofday();
for (i = 0; i < gNumThreads; i++)
{
tNum[i] = i;
pthread_create(&tid[i], NULL, threadFunction, &tNum[i]);
}
for (i = 0; i < gNumThreads; i++)
pthread_join(tid[i], NULL);
stop = wcgettimeofday();
printf("sum = %f\n", gVectorSum);
printf("time = %g\n", stop - start);
Windows API
В Microsoft Windows имеется возможность разработки многопоточных приложений на C++ с помощью "стандартных" системных средств – прикладного программного интерфейса операционной системы Windows.
Windows API. Пример
#include <windows.h>
#include <stdio.h>
#define N 100000000
double a[N + 1], b[N + 1], sum;
int i, j;
double start, stop;
const int gNumSteps = N;
const int gNumThreads = 1;
double gVectorSum = 0;
CRITICAL_SECTION gCS;
DWORD WINAPI threadFunction(LPVOID pArg)
{
int i;
int myNum = *((int *)pArg);
double partialSum = 0; // локально по отношению к каждому потоку
for(i=myNum*(gNumSteps/gNumThreads); i<(myNum+1)*(gNumSteps/gNumThreads); i++)
// используется каждый gNumThreads-й шаг
{
partialSum += a[i] * b[i]; // вычисление частных сумм каждым потоком
}
EnterCriticalSection(&gCS);
gVectorSum += partialSum; // сложение частного результата с глобальным
LeaveCriticalSection(&gCS);
return 0;
}
int main()
{
HANDLE threadHandles[gNumThreads];
int tNum[gNumThreads], i, j;
for (j = 0; j < N; j++)
{
a[j] = 1.031; b[j] = 1.057;
}
printf("Computed value of dot product: ");
InitializeCriticalSection(&gCS);
for ( i = 0; i < gNumThreads; ++i )
{
tNum[i] = i;
threadHandles[i] = CreateThread( NULL, // атрибуты безопасности
0, // размер стека
threadFunction, // функция потока
(LPVOID)&tNum[i],// данные для функции потока
0, // режим запуска потока
NULL); // возвращаемый идентификатор потока
}
WaitForMultipleObjects(gNumThreads, threadHandles, TRUE, INFINITE);
DeleteCriticalSection(&gCS);
printf("sum = %f\n", gVectorSum);
Open Multi-Processing (OpenMP)
OpenMP
Стандарт программного интерфейса приложений для параллельных систем с общей памятью. Поддерживает языки C, C++, Fortran.
Первая версия появилась в 1997 (Fortran) / 1998 (C/C++) годах. Последняя версия OpenMP 3.0 (2008 год). Готовится версия OpenMP 4.0 (2012 год). Разработкой стандарта занимается OpenMP ARB (Architecture Board).
OpenMP. Пример
#include <windows.h>
#include <stdio.h>
#define N 100000000
double a[N + 1], b[N + 1];
int i;
double start, stop;
double gDotProduct = 0;
int main()
{
// инициализация векторов
for (i = 0; i < N; i++)
{
a[i] = 1.034; b[i] = 1.057;
}
printf("Computed value of vector sum: ");
start = omp_get_wtime();
#pragma omp parallel for reduction(+:gDotProduct)
for ( i = 0; i < N; i++ )
{
gDotProduct += a[i] * b[i];
}
stop = omp_get_wtime();
printf("sum = %f\n", gDotProduct);
printf("time = %g\n", stop - start);