37
Лекция 6: Многопоточное программирование Часть 2 (Multithreading programming) Курносов Михаил Георгиевич к.т.н. доцент Кафедры вычислительных систем Сибирский государственный университет телекоммуникаций и информатики http://www.mkurnosov.net

Лекция 6: Многопоточное программирование: часть 2 (Speedup, Amdahl's law, POSIX threads)

Embed Size (px)

Citation preview

Page 1: Лекция 6: Многопоточное программирование: часть 2 (Speedup, Amdahl's law, POSIX threads)

Лекция 6:

Многопоточное программирование

Часть 2

(Multithreading programming)

Курносов Михаил Георгиевич

к.т.н. доцент Кафедры вычислительных систем

Сибирский государственный университет

телекоммуникаций и информатики

http://www.mkurnosov.net

Page 2: Лекция 6: Многопоточное программирование: часть 2 (Speedup, Amdahl's law, POSIX threads)

Программный инструментарий

22Hardware (Multi-core processors, SMP/NUMA)

Kernel thread

Process/thread scheduler

Системные вызовы (System calls)

GNU/Linux Pthreads Apple OS X Cocoa, Pthreads

Уровень ядра(Kernel space)

Операционная система (Operating System)GNU/Linux, Microsoft Windows, Apple OS X, IBM AIX, Oracle Solaris, …

Kernel thread

Kernel thread

Уровень пользователя

(User space)

Системные библиотеки (System libraries)

Thread Thread Thread Thread…

Win32 API/.NET Threads

Thread Thread Thread Thread

Kernel thread

Kernel thread

Kernel thread

Kernel thread

Kernel thread

Intel Threading Building Blocks (TBB) Microsoft Concurrency Runtime Apple Grand Central Dispatch Boost Threads Qthread, MassiveThreads

Прикладные библиотеки Языки программирования

OpenMP(C/C++/Fortran)

Intel Cilk Plus С++11 Threads C11 Threads

C# Threads Java Threads Erlang Threads Haskell Threads

Page 3: Лекция 6: Многопоточное программирование: часть 2 (Speedup, Amdahl's law, POSIX threads)

Программный инструментарий

33Hardware (Multi-core processors, SMP/NUMA)

Kernel thread

Process/thread scheduler

Системные вызовы (System calls)

GNU/Linux Pthreads Apple OS X Cocoa, Pthreads

Уровень ядра(Kernel space)

Операционная система (Operating System)GNU/Linux, Microsoft Windows, Apple OS X, IBM AIX, Oracle Solaris, …

Kernel thread

Kernel thread

Уровень пользователя

(User space)

Системные библиотеки (System libraries)

Thread Thread Thread Thread…

Win32 API/.NET Threads

Thread Thread Thread Thread

Kernel thread

Kernel thread

Kernel thread

Kernel thread

Kernel thread

Intel Threading Building Blocks (TBB) Microsoft Concurrency Runtime Apple Grand Central Dispatch Boost Threads Qthread, MassiveThreads

Прикладные библиотеки Языки программирования

OpenMP(C/C++/Fortran)

Intel Cilk Plus С++11 Threads C11 Threads

C# Threads Java Threads Erlang Threads Haskell Threads

Page 4: Лекция 6: Многопоточное программирование: часть 2 (Speedup, Amdahl's law, POSIX threads)

Коэффициент ускорения (Speedup)

44

Введем обозначения:

o 𝑻(𝒏) – это время выполнения последовательной программы

(sequential program)

o 𝑻𝒑(𝒏) – это время выполнения параллельной программы

(parallel program) на p процессорах

Коэффициент S ускорения параллельной программ (Speedup):

𝑺𝒑 𝒏 =𝑻(𝒏)

𝑻𝒑(𝒏)

Коэффициент ускорения 𝑆𝑝 𝑛 показывает во сколько раз

параллельная программа выполняется на p процессорах быстрее

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

данных размера n

Как правило 𝑆𝑝 𝑛 ≤ 𝑝

Page 5: Лекция 6: Многопоточное программирование: часть 2 (Speedup, Amdahl's law, POSIX threads)

Коэффициент ускорения (Speedup)

55

Введем обозначения:

o 𝑻(𝒏) – это время выполнения последовательной программы

(sequential program)

o 𝑻𝒑(𝒏) – это время выполнения параллельной программы

(parallel program) на p процессорах

Коэффициент S ускорения параллельной программ (Speedup):

𝑺𝒑 𝒏 =𝑻(𝒏)

𝑻𝒑(𝒏)

Цель распараллеливания – достичь линейного ускорения

на максимально большом числе процессоров

𝑺𝒑 𝒏 ≈ 𝒑 или 𝑺𝒑 𝒏 = 𝑶(𝒑) при 𝒑 → ∞

Page 6: Лекция 6: Многопоточное программирование: часть 2 (Speedup, Amdahl's law, POSIX threads)

Коэффициент ускорения (Speedup)

66

Какое время брать за 𝑻(𝒏) – за время выполнения

последовательной программы?

o Время лучшего известного алгоритма (в смысле вычислительной

сложности)?

o Время лучшего теоретически возможного алгоритма?

Что считать временем выполнения 𝑻𝒑 𝒏 параллельной

программы?

o Среднее время выполнения потоков программы?

o Время выполнения потока, завершившего работу первым?

o Время выполнения потока, завершившего работу последним?

Page 7: Лекция 6: Многопоточное программирование: часть 2 (Speedup, Amdahl's law, POSIX threads)

Коэффициент ускорения (Speedup)

77

Какое время брать за 𝑻(𝒏) – за время выполнения

последовательной программы?

o Время лучшего известного алгоритма или время алгоритма,

который подвергается распараллеливанию

Что считать временем выполнения 𝑻𝒑 𝒏 параллельной

программы?

o Время выполнения потока, завершившего работу последним

Page 8: Лекция 6: Многопоточное программирование: часть 2 (Speedup, Amdahl's law, POSIX threads)

Коэффициент ускорения (Speedup)

88

Коэффициент относительного ускорения (Relative speedup) –

отношения времени выполнения параллельной программы на одном

процессоре к времени её выполнения на p процессорах

𝑺𝑹𝒆𝒍𝒂𝒕𝒊𝒗𝒆 𝒑, 𝒏 =𝑻𝟏(𝒏)

𝑻𝒑(𝒏)

Коэффициент эффективности (Efficiency) параллельной программы

𝑬𝒑 𝒏 =𝑺𝒑(𝒏)

𝒏=𝑻(𝒏)

𝒏𝑻𝒑(𝒏)∈ [𝟎, 𝟏]

Коэффициент накладных расходов (Overhead)

𝜺 𝒑, 𝒏 =𝑻𝑺𝒚𝒏𝒄(𝒑, 𝒏)

𝑻𝑪𝒐𝒎𝒑(𝒑, 𝒏)=𝑻𝑻𝒐𝒕𝒂𝒍 𝒑, 𝒏 − 𝑻𝑪𝒐𝒎𝒑(𝒑, 𝒏)

𝑻𝑪𝒐𝒎𝒑(𝒑, 𝒏)

𝑻𝑺𝒚𝒏𝒄(𝒑, 𝒏) – время создания, синхронизации и взаимодействия p потоков

𝑻𝑪𝒐𝒎𝒑(𝒑, 𝒏) – время вычислений в каждом из p потоков

Page 9: Лекция 6: Многопоточное программирование: часть 2 (Speedup, Amdahl's law, POSIX threads)

Коэффициент ускорения (Speedup)

99

0

5

10

15

20

25

30

35

2 4 6 8 10 12 14 16 18 20 22 24 26 28 30 32

S

p

Spee

du

p

Processors

Linear (ideal)

N = 60 * 2^20

N = 40 * 2^20

N = 20 * 2^20

Ускорение программы может расти с увеличением размера входных данных –

время вычислений превосходит накладные расходы на взаимодействия

потоков (управление потоками, синхронизацию, обмен сообщениями, …)

Зависимость коэффициента ускорения Sпараллельного алгоритма X от количества p процессоров

Page 10: Лекция 6: Многопоточное программирование: часть 2 (Speedup, Amdahl's law, POSIX threads)

Коэффициент ускорения (Speedup)

1010

0

5

10

15

20

25

30

35

2 4 6 8 10 12 14 16 18 20 22 24 26 28 30 32

S

p

Spee

du

p

Processors

Linear (ideal)

N = 60 * 2^20

N = 40 * 2^20

N = 20 * 2^20

Ускорение программы может расти с увеличением размера входных данных –

время вычислений превосходит накладные расходы на взаимодействия

потоков (управление потоками, синхронизацию, обмен сообщениями, …)

Зависимость коэффициента ускорения Sпараллельного алгоритма X от количества p процессоров

Линейное ускорение

Sp(n) = 4/5 * p = O(p)

Линейное ускорение

Sp(n) = 1/5 * p = O(p)

Page 11: Лекция 6: Многопоточное программирование: часть 2 (Speedup, Amdahl's law, POSIX threads)

Коэффициент ускорения (Speedup)

1111

Параллельная программа (алгоритм) коэффициент

ускорения, которой линейной растет с увеличением p

называется линейно масштабируемой или просто

масштабируемой (scalable)

Масштабируемая параллельная программа допускает

эффективную реализацию на различном числе

процессоров

Page 12: Лекция 6: Многопоточное программирование: часть 2 (Speedup, Amdahl's law, POSIX threads)

0

5

10

15

20

25

30

35

2 4 6 8 10 12 14 16 18 20 22 24 26 28 30 32

Коэффициент ускорения (Speedup)

1212

S

p

Spee

du

p

Processors

Linear (ideal)

Зависимость коэффициента ускорения Sпараллельных алгоритмов Y и Z от количества p процессоров

Логарифмическое ускорение

Sp(n) = log2p = O(log2p)

𝑺𝒑 𝒏 = 𝒑 = 𝑶( 𝒑)

Page 13: Лекция 6: Многопоточное программирование: часть 2 (Speedup, Amdahl's law, POSIX threads)

Суперлинейное ускорение (Superlinear speedup)

1313

Параллельная программа может характеризоваться суперлинейным

ускорением (Superlinear speedup) – коэффициент ускорения Sp(n) принимает

значение больше p

𝑺𝒑 𝒏 > 𝒑

Причина: иерархическая организация памяти:

Cache – RAM – Local disk (HDD/SSD) – Network storage

Последовательная программ выполняется на одном процессоре

и обрабатывает данные размера n

Параллельная программа имеет p потоков на p процессорах, каждый поток

работает со своей частью данных, большая часть которых может попасть

в кеш-память, в результате в каждом потоке сокращается время доступа

к данным

Тот же самый эффект можно наблюдать имя два уровня иерархической

памяти: диск-память

Page 14: Лекция 6: Многопоточное программирование: часть 2 (Speedup, Amdahl's law, POSIX threads)

Суперлинейное ускорение (Superlinear speedup)

1414http://phycomp.technion.ac.il/~pavelba/Comp_Phys/Project/Project.html

Parallel Molecular Dynamic Simulation MPI, Spatial decomposition;

Cluster nodes: 2 x AMD Opteron Dual Core; InfiniBand network

Superlinear speedup

𝑺𝟖 =𝑻𝟒𝑻𝟖= 𝟐. 𝟑𝟐

Page 15: Лекция 6: Многопоточное программирование: часть 2 (Speedup, Amdahl's law, POSIX threads)

Закон Дж. Амдала (Amdahl’s law)

1515

Пусть имеется последовательная программа c временем выполнения T(n)

Обозначим:

𝒓 ∈ [𝟎, 𝟏] – часть программы, которая может быть распараллелена

(perfectly parallelized)

𝒔 = 𝟏 − 𝒓 – часть программы, которая не может быть распараллелена

(purely sequential)

Закон Дж. Амдала (Gene Amdahl) [1]:

Максимальное ускорение Sp программы на p процессорах равняется

𝑺𝒑 =𝟏

𝟏 − 𝒓 +𝒓𝒑

𝑺∞ = lim𝑝→∞𝑆𝑝 = lim

𝑝→∞

1

1 − 𝑟 +𝑟𝑝

=1

1 − 𝑟=𝟏

𝒔

Amdahl Gene. Validity of the Single Processor Approach to Achieving Large-Scale Computing Capabilities //

AFIPS Conference Proceedings, 1967, pp. 483-485, http://www-inst.eecs.berkeley.edu/~n252/paper/Amdahl.pdf

s

r

Page 16: Лекция 6: Многопоточное программирование: часть 2 (Speedup, Amdahl's law, POSIX threads)

Обоснование закона Дж. Амдала

1616

Время выполнения последовательной программы есть 𝑇(𝑛)

Время выполнения параллельной программы на p процессорах

(время каждого потока) складывается из последовательной части s

и параллельной r:

𝑇𝑝 𝑛 = 𝑇 𝑛 𝑠 +𝑇(𝑛)

𝑝𝑟

Вычислим значение коэффициент ускорения (по определению)

𝑆𝑝 𝑛 =𝑇(𝑛)

𝑇𝑝 𝑛=

𝑇(𝑛)

𝑇 𝑛 𝑠 +𝑇(𝑛)𝑝𝑟=1

𝑠 +𝑟𝑝

=1

(1 − 𝑟) +𝑟𝑝

s

r

Page 17: Лекция 6: Многопоточное программирование: часть 2 (Speedup, Amdahl's law, POSIX threads)

0

5

10

15

20

25

0,1 0,2 0,3 0,4 0,5 0,6 0,7 0,8 0,9 0,95

Закон Дж. Амдала (Amdahl’s law)

1717

r

Зависимость коэффициента S∞ ускорения параллельной программы от доли r распараллеленного кода

S∞

Page 18: Лекция 6: Многопоточное программирование: часть 2 (Speedup, Amdahl's law, POSIX threads)

Закон Дж. Амдала (Amdahl’s law)

1818

Допущения закона Амдала

Последовательный алгоритм является наиболее оптимальным способом

решения задачи. Возможны ситуации когда параллельная программа

(алгоритм) эффективнее решает задачу (может эффективнее использовать

кеш-память, конвейер, SIMD-инструкции, …)

Время выполнения параллельной программы оценивается через время

выполнения последовательной, однако потоки параллельной программы

могут выполнятся эффективнее

𝑇𝑝 𝑛 = 𝑇 𝑛 𝑠 +𝑇(𝑛)

𝑝𝑟

Ускорение Sp(n) оценивается для фиксированного размера n данных при

любых значениях p. На практике при увеличении числа используемых

процессоров размер n входных данных также увеличивают, так как может

быть доступно больше памяти

Page 19: Лекция 6: Многопоточное программирование: часть 2 (Speedup, Amdahl's law, POSIX threads)

Закон Дж. Амдала (Amdahl’s law)

1919

Следствие. Увеличение параллельной части r программ важнее,

чем увеличение количества процессоров

0

10

20

30

40

50

60

70

80

90

2 4 8 16 32

r = 30%

r = 60%

r = 90%

p

Зависимость времени Tp(n) выполнения параллельной программыот количества p процессоров и доли r распараллеленного кода

(время в % от времени T1(n))

T, %

Page 20: Лекция 6: Многопоточное программирование: часть 2 (Speedup, Amdahl's law, POSIX threads)

Закон Дж. Амдала (Amdahl’s law)

2020

Следствие. Увеличение параллельной части r программ важнее,

чем увеличение количества процессоров

0

10

20

30

40

50

60

70

80

90

2 4 8 16 32

r = 30%

r = 60%

r = 90%

p

Зависимость времени Tp(n) выполнения параллельной программыот количества p процессоров и доли r распараллеленного кода

(время в % от времени T1(n))

T, %Удвоение числа процессоров

сокращает время с 85% до 77,5%

Удвоение доли параллельного кода сокращает время

с 85% до 70%

Page 21: Лекция 6: Многопоточное программирование: часть 2 (Speedup, Amdahl's law, POSIX threads)

Закон Густафсона-Барсиса

2121

В 1980-х годах показали, что некоторые практические приложения могут

масштабироваться лучше (почти линейно), чем предсказывает закон Амдала!

Пусть имеется последовательная программа c временем выполнения T(n)

Обозначим 𝒔 ∈ [𝟎, 𝟏] – часть программы, которая не может быть распараллелена

(purely sequential)

Закон Густафсона-Барсиса (Gustafson–Barsis' law) [1]:

Масштабируемое ускорение Sp программы на p процессорах равняется

𝑺𝒑 = 𝒑 − 𝒔(𝒑 − 𝟏)

Обоснование

Пусть a – время последовательной части, b – время параллельной части

𝑻𝒑 𝒏 = 𝒂 + 𝒃, 𝑻 𝒏 = 𝒂 + 𝒑𝒃

𝐬 = 𝒂/(𝒂 + 𝒃), 𝑺𝒑 𝒏 = 𝒔 + 𝒑 𝟏 − 𝒔 = 𝒑 − 𝒔(𝒑 − 𝟏)

Время выполнения последовательной программы выражается через время выполнения

параллельной

Reevaluating Amdahl's Law, John L. Gustafson, Communications of the ACM 31(5), 1988. pp. 532-533 //

http://www.scl.ameslab.gov/Publications/Gus/AmdahlsLaw/Amdahls.html

Page 22: Лекция 6: Многопоточное программирование: часть 2 (Speedup, Amdahl's law, POSIX threads)

POSIX Threads

2222

POSIX Threads – это стандарт (POSIX.1c Threads extensions

(IEEE Std 1003.1c-1995)), в котором определяется API

для создания и управления потоками

Библиотека pthread (pthread.h) ~ 100 функций

Thread management - creating, joining threads etc.

Mutexes

Condition variables

Synchronization between threads using read/write locks and

barriers

Семфафоры POSIX (префикс sem_) могут работать

с потоками pthread, но не являются частью стандарта

(определены в стандарте POSIX.1b, Real-time extensions

(IEEE Std 1003.1b-1993))

Page 23: Лекция 6: Многопоточное программирование: часть 2 (Speedup, Amdahl's law, POSIX threads)

POSIX pthreads API

2323

Всем типы данных и функции начинаются с префикса pthread_

Prefix Functional group

pthread_Threads themselves and miscellaneous subroutines

pthread_attr_ Thread attributes objects

pthread_mutex_ Mutexes

pthread_mutexattr_ Mutex attributes objects.

pthread_cond_ Condition variables

pthread_condattr_ Condition attributes objects

pthread_key_ Thread-specific data keys

pthread_rwlock_ Read/write locks

pthread_barrier_ Synchronization barriers

https://computing.llnl.gov/tutorials/pthreads

Page 24: Лекция 6: Многопоточное программирование: часть 2 (Speedup, Amdahl's law, POSIX threads)

POSIX pthreads API

2424

Compiler / Platform Compiler Command Description

Intel GNU/Linux

icc -pthread C

icpc -pthread C++

PGIGNU/Linux

pgcc -lpthread C

pgCC -lpthread C++

GNU GCCGNU/Linux, Blue Gene

gcc -pthread GNU C

g++ -pthread GNU C++

IBMBlue Gene

bgxlc_r / bgcc_r C (ANSI / non-ANSI)

bgxlC_r, bgxlc++_r C++

Компиляция программы с поддержкой POSIX pthreads API

Page 25: Лекция 6: Многопоточное программирование: часть 2 (Speedup, Amdahl's law, POSIX threads)

Создание потоков

2525

int pthread_create(pthread_t *restrict thread, const pthread_attr_t *restrict attr, void *(*start_routine)(void*), void *restrict arg);

Создает поток с заданными атрибутами attr и запускает в нем

функцию start_routine, передавая ей аргумент arg

Количество создаваемых в процессе потоков стандартом

не ограничивается и зависит от реализации

Размер стека потока можно задать через атрибут потока attr

Размер стека по умолчанию: getrlimit(RLIMIT_STRACK, &rlim);

$ ulimit –s # The maximum stack size

8192

$ ulimit –u # The maximum number of processes

1024 # available to a single usere

Page 26: Лекция 6: Многопоточное программирование: часть 2 (Speedup, Amdahl's law, POSIX threads)

Завершение потоков

2626

Возврат (return) из стартовой функции (start_routine)

Вызов pthread_exit()

Вызов pthread_cancel() другим потоком

Процесс (и его потоки) завершаются вызовом exit()

Page 27: Лекция 6: Многопоточное программирование: часть 2 (Speedup, Amdahl's law, POSIX threads)

#include <pthread.h> #define NTHREADS 5

void *thread_fun(void *threadid) { long tid = (long)threadid; printf("Hello from %ld!\n", tid); pthread_exit(NULL);

}

int main(int argc, char *argv[]) { pthread_t threads[NTHREADS]; int rc; long t;

for (t = 0; t < NTHREADS; t++) { rc = pthread_create(&threads[t], NULL, thread_fun, (void *)t); if (rc) {

printf("ERROR %d\n", rc); exit(-1);

} } pthread_exit(NULL);

}

Создание и завершение потоков

2727

Page 28: Лекция 6: Многопоточное программирование: часть 2 (Speedup, Amdahl's law, POSIX threads)

#include <pthread.h> #define NTHREADS 5

void *thread_fun(void *threadid) { long tid = (long)threadid; printf("Hello from %ld!\n", tid); pthread_exit(NULL);

}

int main(int argc, char *argv[]) { pthread_t threads[NTHREADS]; int rc; long t;

for (t = 0; t < NTHREADS; t++) { rc = pthread_create(&threads[t], NULL, thread_fun, (void *)t); if (rc) {

printf("ERROR %d\n", rc); exit(-1);

} } pthread_exit(NULL);

}

Создание и завершение потоков

2828

$ gcc –pthread –o prog ./prog.c

$ ./prog

Hello from 1!

Hello from 4!

Hello from 0!

Hello from 2!

Hello from 3!

Page 29: Лекция 6: Многопоточное программирование: часть 2 (Speedup, Amdahl's law, POSIX threads)

Ожидание потоков

2929

Функция pthread_join() – позволяет дождаться завершения заданного

потока

Поток может быть типа “detached” или “joinable” (default)

К detached-потоку не применима функция pthread_join

(поток создается и существует независимо от других)

Joinable-поток требует хранения дополнительных данных

Тип потока можно задать через его атрибуты или вызвав функцию

pthread_detach

Page 30: Лекция 6: Многопоточное программирование: часть 2 (Speedup, Amdahl's law, POSIX threads)

#include <pthread.h> #define NTHREADS 5

// ...

int main(int argc, char *argv[]) { pthread_t threads[NTHREADS]; int rc; long t;void *status;

for (t = 0; t < NTHREADS; t++) { rc = pthread_create(&threads[t], NULL, thread_fun,

(void *)t); }

for (t = 0; t < NTHREADS; t++) { rc = pthread_join(threads[t], &status);

} pthread_exit(NULL);

}

Ожидание потоков

3030

Page 31: Лекция 6: Многопоточное программирование: часть 2 (Speedup, Amdahl's law, POSIX threads)

Синхронизация потоков

3131

Функция pthread_self() – возвращает идентификатор потока

Функция pthread_equal() – позволяет сравнить идентификаторы двух

потоков

Page 32: Лекция 6: Многопоточное программирование: часть 2 (Speedup, Amdahl's law, POSIX threads)

Взаимные исключения (mutex)

3232

Mutex (mutual exclusion) – это объект синхронизации “взаимное

исключение”

Мьютексы используются для создания критических секций

(critical sections) – областей кода, которые выполняются в любой

момент времени только одним потоком

В критических секциях, как правило, содержится код работы

с разделяемыми переменными

pthread_mutex_init() – инициализирует мьютекс

pthread_mutex_destroy() – уничтожает мьютекс

pthread_mutex_lock() – блокирует выполнение потока,

пока он не захватит (acquire) мьютекс

pthread_mutex_trylock() – осуществляет попытку захватить мьютекс

pthread_mutex_unlock() – освобождает (release) мьютекс

Page 33: Лекция 6: Многопоточное программирование: часть 2 (Speedup, Amdahl's law, POSIX threads)

node_t *llist_delete(int value) {

node_t *prev, *current; prev = &head;

pthread_mutex_lock(&prev->lock); while ((current = prev->link) != NULL) {

pthread_mutex_lock(&current->lock); if (current->value == value) {

prev->link = current->link; pthread_mutex_unlock(&current->lock); pthread_mutex_unlock(&prev->lock); current->link = NULL; return current;

} pthread_mutex_unlock(&prev->lock); prev = current;

} pthread_mutex_unlock(&prev->lock); return NULL;

}

Взаимные исключения (mutex)

3333

Page 34: Лекция 6: Многопоточное программирование: часть 2 (Speedup, Amdahl's law, POSIX threads)

0,00

0,50

1,00

1,50

2,00

2,50

3,00

3,50

4,00

4,50

0,00 0,10 0,20 0,30 0,40 0,50 0,60 0,70 0,80 0,90

Вычисление числа π

3434

𝜋 =

0

14

1 + 𝑥2𝑑𝑥 𝜋 ≈ ℎ

𝑖=1

𝑛4

1 + (ℎ(𝑖 − 0.5))2ℎ =1

𝑛

Приближенное вычисление числа π

Page 35: Лекция 6: Многопоточное программирование: часть 2 (Speedup, Amdahl's law, POSIX threads)

#include <stdio.h>#include <stdlib.h>#include <pthread.h>

volatile long double pi = 0.0; pthread_mutex_t piLock; long double intervals; int numThreads;

void *computePI(void *id){

long double x, width, localSum = 0; int i, threadID = *((int*)id); width = 1.0 / intervals; for (i = threadID ; i < intervals; i += numThreads) {

x = (i + 0.5) * width; localSum += 4.0 / (1.0 + x * x);

} localSum *= width; pthread_mutex_lock(&piLock); pi += localSum; pthread_mutex_unlock(&piLock); return NULL;

}

pi.c

3535

Page 36: Лекция 6: Многопоточное программирование: часть 2 (Speedup, Amdahl's law, POSIX threads)

int main(int argc, char **argv){

pthread_t *threads; void *retval; int *threadID; int i;

if (argc == 3) { intervals = atoi(argv[1]); numThreads = atoi(argv[2]); threads = malloc(numThreads * sizeof(pthread_t)); threadID = malloc(numThreads * sizeof(int)); pthread_mutex_init(&piLock, NULL); for (i = 0; i < numThreads; i++) {

threadID[i] = i; pthread_create(&threads[i], NULL, computePI, threadID + i);

} for (i = 0; i < numThreads; i++)

pthread_join(threads[i], &retval);

printf("Estimation of pi is %32.30Lf \n", pi); } else {

printf("Usage: ./a.out <numIntervals> <numThreads>\n"); } return 0;

}

pi.c (продолжение)

3636

Page 37: Лекция 6: Многопоточное программирование: часть 2 (Speedup, Amdahl's law, POSIX threads)

Ссылки

3737

Эхтер Ш., Робертс Дж. Многоядерное программирование. – СПб.: Питер,

2010. – 316 с.

Эндрюс Г.Р. Основы многопоточного, параллельного и распределенного

программирования. – М.: Вильямс, 2003. – 512 с.

Darryl Gove. Multicore Application Programming: for Windows, Linux, and

Oracle Solaris. – Addison-Wesley, 2010. – 480 p.

Maurice Herlihy, Nir Shavit. The Art of Multiprocessor Programming. –

Morgan Kaufmann, 2008. – 528 p.

Richard H. Carver, Kuo-Chung Tai. Modern Multithreading : Implementing,

Testing, and Debugging Multithreaded Java and C++/Pthreads/Win32

Programs. – Wiley-Interscience, 2005. – 480 p.

Anthony Williams. C++ Concurrency in Action: Practical Multithreading. –

Manning Publications, 2012. – 528 p.

Träff J.L. Introduction to Parallel Computing //

http://www.par.tuwien.ac.at/teach/WS12/ParComp.html