Опубликован: 11.10.2012 | Уровень: для всех | Доступ: платный | ВУЗ: Санкт-Петербургский государственный университет
Лекция 1:

Обзор средств разработки высокопроизводительных приложений

Лекция 1: 123 || Лекция 2 >

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); 

Лекция 1: 123 || Лекция 2 >
Константин Белюстин
Константин Белюстин
Украина, г. Киев
Андрей Частухин
Андрей Частухин
Россия