Санкт-Петербургский государственный университет
Опубликован: 11.10.2012 | Доступ: свободный | Студентов: 956 / 174 | Длительность: 05:14:00
Специальности: Программист, Системный архитектор
Теги:
Лекция 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);