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

Лекция 5: Многопоточное программирование: часть 1 (Multithreading programming: multi-core processors, CPU affinity, memory ordering)

Jun 16, 2015

Download

Technology

Welcome message from author
This document is posted to help you gain knowledge. Please leave a comment to let me know what you think about it! Share it to your friends and learn new things together.
Transcript
Page 1: Лекция 5: Многопоточное программирование: часть 1 (Multithreading programming: multi-core processors, CPU affinity, memory ordering)

Лекция 5:

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

Часть 1

(Multithreading programming)

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

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

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

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

http://www.mkurnosov.net

Page 2: Лекция 5: Многопоточное программирование: часть 1 (Multithreading programming: multi-core processors, CPU affinity, memory ordering)

Уровень параллелизма Аппаратурная реализация Granularity

Параллелизм уровня

инструкций

ILP – Instruction Level Parallelism

Вычислительное ядро процессора

(Processor execution core/engine)

Мелкозернистый

параллелизм

(Fine-grained

parallelism)

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

TLP – Thread Level Parallelism

Многоядерный процессор

(Multi-core processor),

многопроцессорная система

с общей памятью (Shared memory

system, SMP/ NUMA)

Крупнозернистый

параллелизм

(Coarse-grained

parallelism)

Параллелизм уровня процессов

PLP – Process Level Parallelism

Вычислительная система

с распределенной памятью

(Distributed memory system)

Уровни параллелизма

22

Page 3: Лекция 5: Многопоточное программирование: часть 1 (Multithreading programming: multi-core processors, CPU affinity, memory ordering)

Одноядерные процессоры (Single-core processors)

33

Состояние ядра

(Architectural State)

Вычислительное ядро

(Execution Engine)

Кеш-память

(Cache)

Frontend

(Fetch, Decode)

Состояние ядра

(Architectural State)

Вычислительное ядро

(Execution Engine)

Кеш-память

(Cache)

Frontend

(Fetch, Decode)

Состояние ядра

(Architectural State)

Одноядерный процессор

(Single-core processor)

� Superscalar pipeline

� Out-of-order execution

� SIMD instructions

� VLIW

Одноядерный

процессор

с поддержкой

одновременной

многопоточности

(Simultaneous

multithreading , SMT)

� 2 потока разделяют

суперскалярный

конвейер

ILP

ILP

Chip

Chip

Page 4: Лекция 5: Многопоточное программирование: часть 1 (Multithreading programming: multi-core processors, CPU affinity, memory ordering)

Многопроцессорные системы (SMP, NUMA)

44

Состояние ядра

(Architectural State)

Вычислительное ядро

(Execution Engine)

Кеш-

память

(Cache)

Frontend

(Fetch, Decode)

Состояние ядра

(Architectural State)

Вычислительное ядро

(Execution Engine)

Кеш-

память

(Cache)

Frontend

(Fetch, Decode)

Разделяемая память (Shared memory, RAM)

ILP ILP

TLP/PLP

� SMP/NUMA-системы

� Процессоры независимы – независимые чипы (chip), установлены в разные

разъемы на системной плате и имеют общий доступ к оперативной памяти

� Операционная система предоставляет доступ к совокупности логических

процессоров (logical processors)

Chip Chip

Page 5: Лекция 5: Многопоточное программирование: часть 1 (Multithreading programming: multi-core processors, CPU affinity, memory ordering)

Многоядерные процессоры (Multi-core processors)

55

� Процессорные ядра размещены на одном чипе (chip)

� Ядра процессора могу разделять некоторые ресурсы

(например, кеш-память)

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

логических процессоров (logical processors)

Состояние ядра

(Architectural State)

Вычислительное ядро

(Execution Engine)

Кеш-

память

(Cache)

Frontend

(Fetch, Decode)

Состояние ядра

(Architectural State)

Вычислительное ядро

(Execution Engine)

Кеш-

память

(Cache)

Frontend

(Fetch, Decode)

ILP ILP

TLP/PLP

Chip

Page 6: Лекция 5: Многопоточное программирование: часть 1 (Multithreading programming: multi-core processors, CPU affinity, memory ordering)

Многоядерные процессоры (Multi-core processors)

66

� Процессорные ядра размещены на одном чипе (chip)

� Ядра процессора могу разделять некоторые ресурсы

(например, кеш-память)

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

логических процессоров (logical processors)

Состояние ядра

(Architectural State)

Вычислительное ядро

(Execution Engine)

Кеш-

память

(Cache)

Frontend

(Fetch, Decode)

Состояние ядра

(Architectural State)

Вычислительное ядро

(Execution Engine)

Кеш-

память

(Cache)

Frontend

(Fetch, Decode)

ILP ILP

Chip

Разделяемая кеш-память (Shared cache)

TLP/PLP

Page 7: Лекция 5: Многопоточное программирование: часть 1 (Multithreading programming: multi-core processors, CPU affinity, memory ordering)

Многоядерные процессоры с SMT

77

� Многоядерный процессор может поддерживать

одновременную многопоточность (Simultaneous multithreading – SMT,

Intel Hyper-threading, Fujitsu Vertical Multithreading)

� Каждое ядро может выполнять несколько потоков на своем

суперскалярном конвейере (2-way SMT, 4-way SMT, 8-way SMT, …)

� Операционная система представляет каждый SMT-поток как логический

процессор

Состояние ядра

(Architectural State)

Кеш-

память

(Cache)

Состояние ядра

(Architectural State)

Вычислительное ядро

(Execution Engine)

Frontend

(Fetch, Decode)

ILP

Состояние ядра

(Architectural State)

Кеш-

память

(Cache)

Состояние ядра

(Architectural State)

Вычислительное ядро

(Execution Engine)

Frontend

(Fetch, Decode)

ILP

TLP/PLP

Page 8: Лекция 5: Многопоточное программирование: часть 1 (Multithreading programming: multi-core processors, CPU affinity, memory ordering)

Многоядерные процессоры с SMT

8

Состояние ядра

(Architectural State)

Кеш-

память

(Cache)

Состояние ядра

(Architectural State)

Вычислительное ядро

(Execution Engine)

Frontend

(Fetch, Decode)

ILP

Состояние ядра

(Architectural State)

Кеш-

память

(Cache)

Состояние ядра

(Architectural State)

Вычислительное ядро

(Execution Engine)

Frontend

(Fetch, Decode)

ILP

Thread 0 Thread 1

� В системе 4 логических процессора

� Потоки 0 и 1 выполняются на ресурсах одного ядра – привязаны

к логическим процессорам SMT (например, Intel Hyper-Threading)

� В этом случае оба потока разделяют ресурсы одного суперскалярного

конвейера ядра – конкурируют за доступ к нему (concurrency)

� Задействован только параллелизм уровня инструкций (ILP),

второе ядро простаивает

Instruction Level Parallelism only!

Concurrency

Page 9: Лекция 5: Многопоточное программирование: часть 1 (Multithreading programming: multi-core processors, CPU affinity, memory ordering)

Многоядерные процессоры с SMT

9

Состояние ядра

(Architectural State)

Кеш-

память

(Cache)

Состояние ядра

(Architectural State)

Вычислительное ядро

(Execution Engine)

Frontend

(Fetch, Decode)

ILP

Состояние ядра

(Architectural State)

Кеш-

память

(Cache)

Состояние ядра

(Architectural State)

Вычислительное ядро

(Execution Engine)

Frontend

(Fetch, Decode)

ILP

Thread 0 Thread 1

� В системе 4 логических процессора

� Потоки 0 и 1 выполняются на ресурсах разных ядер – привязаны

к логическим процессорам SMT ядра 0 и 1

� В этом случае оба потока выполняются на суперскалярных конвейерах

разных ядер

� Задействован параллелизм уровня потоков (TLP) и инструкций (ILP)

Thread Level Parallelism +

Instruction Level Parallelism

Page 10: Лекция 5: Многопоточное программирование: часть 1 (Multithreading programming: multi-core processors, CPU affinity, memory ordering)

NUMA – Non-Uniform Memory Architecture

1010

� У каждого многоядерного процессора имеется локальная память

� Доступ к удаленной памяти занимает больше времени

(~ на 30%, HyperTransport)

� SUMO – Sufficiently Uniform Memory Organization

AMD Hyper-Transport

Page 11: Лекция 5: Многопоточное программирование: часть 1 (Multithreading programming: multi-core processors, CPU affinity, memory ordering)

NUMA - Non-Uniform Memory Architecture

1111

Intel Quick Path Interconnect (QPI)

Page 12: Лекция 5: Многопоточное программирование: часть 1 (Multithreading programming: multi-core processors, CPU affinity, memory ordering)

NUMA - Non-Uniform Memory Architecture

1212

Узел на базе Intel Nehalem

2 процессора Intel Xeon 5600 (Westmere) 6-core, 2 IOH

Page 13: Лекция 5: Многопоточное программирование: часть 1 (Multithreading programming: multi-core processors, CPU affinity, memory ordering)

NUMA - Non-Uniform Memory Architecture

1313

� Как операционной системе выделять память для

процессов – с локального узла? с удаленного?

чередовать локальный узел и удаленный?

Page 14: Лекция 5: Многопоточное программирование: часть 1 (Multithreading programming: multi-core processors, CPU affinity, memory ordering)

NUMA - Non-Uniform Memory Architecture

1414

� Режим управления памятью NUMA-машины можно,

как правило, задать в настройках BIOS

� Распространенные режимы (Memory modes):

� NUMA Mode – у каждого узла имеется локальная

память, операционная система учитывает топологию

при выделении памяти

� Node Interleave (чередование памяти между узлами) –

пространство адресов разбивается на регионы

и циклически заполняется со всех узлов (round robin),

операционная систем “думает”, что доступ к памяти

“однороден”

Page 15: Лекция 5: Многопоточное программирование: часть 1 (Multithreading programming: multi-core processors, CPU affinity, memory ordering)

NUMA – Non-Uniform Memory Architecture

1515

Memory latency and bandwidth accessing local,

remote memory for a PowerEdge R610 server (Dual Intel Xeon X5550 Nehalem, 6 x 4GB 1333 MHz RDIMMS)

http://i.dell.com/sites/content/business/solutions/whitepapers/ja/Documents/HPC_Dell_11g_BIOS_Options_jp.pdf

Page 16: Лекция 5: Многопоточное программирование: часть 1 (Multithreading programming: multi-core processors, CPU affinity, memory ordering)

Мобильные телефоны (Mobile phones)

1616

Samsung Galaxy S4 (GT-I9505)

� Quad-core Snapdragon 600

(1.9 GHz with LTE, ARMv7, CPU Krai 300)

� Pipeline: 11 stage integer pipeline

(3-way decode, 4-way out-of-order

speculative issue superscalar)

� SIMD: 128-bit wide NEON

� L0 cache: 4 KB + 4 KB direct mapped

� L1 cache: 16 KB + 16 KB 4-way set associative

� L2 cache: 2 MB 8-way set associative

� Technology process: 28 nm

Page 17: Лекция 5: Многопоточное программирование: часть 1 (Multithreading programming: multi-core processors, CPU affinity, memory ordering)

Мобильные телефоны (Mobile phones)

1717

Apple iPhone 5S

� Dual-core Apple A7 (CPU + GPU)

(CPU 1.3 GHz, 64-bit ARMv8)

� SIMD: 128-bit wide NEON

� L1 cache:

per core 64 KB L1i, 64 KB L1d

� L2 cache: shared 1 MB

� Technology process: 28 nm (manufactured by Samsung)

Page 18: Лекция 5: Многопоточное программирование: часть 1 (Multithreading programming: multi-core processors, CPU affinity, memory ordering)

� 64 cores: Intel P54C (Pentium)

� Pipeline: in-order, 4-way SMT, 512-bit SIMD

� Кольцевая шина (1024 бит, ring bus)

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

� Память GDDR5

� Устанавливается в PCI Express слот

SMP-система

(256 логических

процессоров)

Intel Xeon Phi Coprocessor (Intel MIC)

1818

Page 19: Лекция 5: Многопоточное программирование: часть 1 (Multithreading programming: multi-core processors, CPU affinity, memory ordering)

Intel Xeon Phi Coprocessor (Intel MIC)

1919

http://www.anandtech.com/show/6451/the-xeon-phi-at-work-at-tacc

Page 20: Лекция 5: Многопоточное программирование: часть 1 (Multithreading programming: multi-core processors, CPU affinity, memory ordering)

GPU – Graphics Processing Unit

2020

� NVidia Kepler

� AMD FirePro

� Специализированные

мультипроцессоры (SMP)

� Каждый процессор

многоядерный

Page 21: Лекция 5: Многопоточное программирование: часть 1 (Multithreading programming: multi-core processors, CPU affinity, memory ordering)

Многоядерные процессоры (Multi-core processors)

2121

Sony Playstation 3

IBM Cell (2-way SMT

PowerPC core + 6 SPE)

Microsoft XBox 360

IBM Xenon

(3 cores with 2-way SMT)

Tilera TILEPro64

(64 cores, VLIW, mesh)

Cisco Routers

Multi-core MIPS processors

Page 22: Лекция 5: Многопоточное программирование: часть 1 (Multithreading programming: multi-core processors, CPU affinity, memory ordering)

Многоядерные процессоры (Multi-core processors)

22

Sony Playstation 3

IBM Cell (2-way SMT

PowerPC core + 6 SPE)

Microsoft XBox 360

IBM Xenon

(3 cores with 2-way SMT)

Tilera TILEPro64

(64 cores, VLIW, mesh)

Cisco Routers

Multi-core MIPS processors

Что со всем этим делать?

� Как (на чем) разрабатывать программы для такого

количества многоядерных архитектур?

� Как быть с переносимостью программ?

� Как быть с переносимостью производительности

программ?

� Все ли алгоритмы эффективно распараллеливаются?

� …

22

Page 23: Лекция 5: Многопоточное программирование: часть 1 (Multithreading programming: multi-core processors, CPU affinity, memory ordering)

Многоядерные процессоры (Multi-core processors)

2323

“Concurrency is the next major revolution

in how we write software”

-- Herb Sutter*

[*] Herb Sutter. The Free Lunch Is Over: A Fundamental Turn Toward Concurrency in

Software // http://www.gotw.ca/publications/concurrency-ddj.htm

Page 24: Лекция 5: Многопоточное программирование: часть 1 (Multithreading programming: multi-core processors, CPU affinity, memory ordering)

Системы с распределенной памятью

2424

CPU0

Коммуникационная сеть (Interconnect, Communication network)

Cache

Разделяемая память

(Shared memory)

CPU1

Cache

CPU2

Cache

CPU3

Cache

Compute node 0

CPU0

Cache

Разделяемая память

(Shared memory)

CPU1

Cache

CPU2

Cache

CPU3

Cache

Compute node 1

� Вычислительная система с распределенной памятью

(Distributed memory computer system) – совокупность вычислительных узлов,

взаимодействие между которыми осуществляется через коммуникационную

сеть (InfiniBand, Gigabit Ethernet, Cray Gemeni, Fujitsu Tofu, …)

� Каждый узел имеет множество процессоров/ядер, взаимодействующих через

разделяемую память (Shared memory)

� Процессоры могут быть многоядерными,

ядра могут поддерживать одновременную

многопоточность (SMT)

� http://www.top500.org

� http://www.green500.org

� http://www.graph500.org

Page 25: Лекция 5: Многопоточное программирование: часть 1 (Multithreading programming: multi-core processors, CPU affinity, memory ordering)

Системы с распределенной памятью

2525

CPU0

Коммуникационная сеть (Interconnect, Communication network)

Cache

Разделяемая память

(Shared memory)

CPU1

Cache

CPU2

Cache

CPU3

Cache

Compute node 0

CPU0

Cache

Разделяемая память

(Shared memory)

CPU1

Cache

CPU2

Cache

CPU3

Cache

Compute node 1

� Вычислительная система с распределенной памятью

(Distributed memory computer system) – совокупность вычислительных узлов,

взаимодействие между которыми осуществляется через коммуникационную

сеть (InfiniBand, Gigabit Ethernet, Cray Gemeni, Fujitsu Tofu, …)

� Каждый узел имеет множество процессоров/ядер, взаимодействующих через

разделяемую память (Shared memory)

� Процессоры могут быть многоядерными,

ядра могут поддерживать одновременную

многопоточность (SMT)

ILP ILP ILP ILP

TLP/PLP

ILP ILP ILP ILP

TLP/PLP

TLP/PLP (Message Passing)

� http://www.top500.org

� http://www.green500.org

� http://www.graph500.org

Page 26: Лекция 5: Многопоточное программирование: часть 1 (Multithreading programming: multi-core processors, CPU affinity, memory ordering)

CPU Topology Intel64

2626

� На процессорах Intel64 инструкция CPUID позволяет получить

информацию о привязке логических процессоров операционной

системы к аппаратным потокам (SMT), ядрам (cores)

и чипам (chips, packages)

� Каждый логический процессор имеет уникальный APIC ID

(доступ к его полям осуществляется через CPUID)

� Intel 64 Architecture Processor Topology Enumeration // http://software.intel.com/en-us/articles/intel-64-architecture-processor-topology-enumeration

� OSDev Detecting CPU // http://wiki.osdev.org/Detecting_CPU_Topology_(80x86)

� https://www.kernel.org/doc/Documentation/cputopology.txt

Page 27: Лекция 5: Многопоточное программирование: часть 1 (Multithreading programming: multi-core processors, CPU affinity, memory ordering)

CPU Topology GNU/Linux (/sys)

2727

$ ls /sys/devices/system/cpu/cpu0/topology/

total 0

drwxr-xr-x. 2 root root 0 Sep 29 08:05 .

drwxr-xr-x. 8 root root 0 Sep 29 08:05 ..

-r--r--r--. 1 root root 4096 Sep 29 08:05 core_id

-r--r--r--. 1 root root 4096 Sep 29 08:05 core_siblings

-r--r--r--. 1 root root 4096 Sep 29 15:56 core_siblings_list

-r--r--r--. 1 root root 4096 Sep 29 08:05 physical_package_id

-r--r--r--. 1 root root 4096 Sep 29 08:05 thread_siblings

-r--r--r--. 1 root root 4096 Sep 29 08:05 thread_siblings_list

� physical_package_id – номер физического процессора (сокета)

� core_id – номер ядра физического процессора cpuX

� core_siblings – битовая маска ядер, размещенных на одном физическом

процессоре

� core_siblings_list – список номеров ядер, размещенных на одном физическом

процессоре

� thread_siblings – битовая маска аппаратных потоков (SMT, Hype-Threading),

принадлежащих одному ядру

� thread_siblings_list – список номеров аппаратных потоков (SMT, Hype-Threading),

принадлежащих одному ядру

Intel Core i5-2520M

(2 cores,

Hyper-Threading on)

Page 28: Лекция 5: Многопоточное программирование: часть 1 (Multithreading programming: multi-core processors, CPU affinity, memory ordering)

CPU Topology GNU/Linux (/sys)

2828

$ ls /sys/devices/system/cpu/cpu0/topology/

total 0

drwxr-xr-x. 2 root root 0 Sep 29 08:05 .

drwxr-xr-x. 8 root root 0 Sep 29 08:05 ..

-r--r--r--. 1 root root 4096 Sep 29 08:05 core_id

-r--r--r--. 1 root root 4096 Sep 29 08:05 core_siblings

-r--r--r--. 1 root root 4096 Sep 29 15:56 core_siblings_list

-r--r--r--. 1 root root 4096 Sep 29 08:05 physical_package_id

-r--r--r--. 1 root root 4096 Sep 29 08:05 thread_siblings

-r--r--r--. 1 root root 4096 Sep 29 08:05 thread_siblings_list

Logical CPU0

� physical_package_id = 0

� core_id = 0

� core_siblings = 00000000,00000000,00000000,0000000f

� core_siblings_list = 0-3

� thread_siblings = 00000000,00000000,00000000,00000003

� thread_siblings_list = 0-1

Intel Core i5-2520M

(2 cores,

Hyper-Threading on)

Core 0

Architectural State 1

(H-T/SMT core)

Architectural State 0

(H-T/SMT core)

Core 1

Architectural State 1

(H-T/SMT core)Architectural State 0

(H-T/SMT core)

Intel Core i5-2520M: package 0

Page 29: Лекция 5: Многопоточное программирование: часть 1 (Multithreading programming: multi-core processors, CPU affinity, memory ordering)

CPU Topology GNU/Linux (/sys)

2929

$ ls /sys/devices/system/cpu/cpu3/topology/

total 0

drwxr-xr-x. 2 root root 0 Sep 29 08:05 .

drwxr-xr-x. 8 root root 0 Sep 29 08:05 ..

-r--r--r--. 1 root root 4096 Sep 29 08:05 core_id

-r--r--r--. 1 root root 4096 Sep 29 08:05 core_siblings

-r--r--r--. 1 root root 4096 Sep 29 15:56 core_siblings_list

-r--r--r--. 1 root root 4096 Sep 29 08:05 physical_package_id

-r--r--r--. 1 root root 4096 Sep 29 08:05 thread_siblings

-r--r--r--. 1 root root 4096 Sep 29 08:05 thread_siblings_list

Logical CPU3

� physical_package_id = 0

� core_id = 1

� core_siblings = 00000000,00000000,00000000,0000000f

� core_siblings_list = 0-3

� thread_siblings = 00000000,00000000,00000000,0000000c

� thread_siblings_list = 2-3

Intel Core i5-2520M

(2 cores,

Hyper-Threading on)

Core 0

Architectural State 1

(H-T/SMT core)

Core 1

Architectural State 1

(H-T/SMT core)Architectural State 0

(H-T/SMT core)

Intel Core i5-2520M: package 0

Architectural State 0

(H-T/SMT core)

Page 30: Лекция 5: Многопоточное программирование: часть 1 (Multithreading programming: multi-core processors, CPU affinity, memory ordering)

CPU Topology GNU/Linux (/proc)

3030

$ cat /proc/cpuinfo

processor : 0

physical id : 0

siblings : 4

core id : 0

cpu cores : 2

apicid : 0

initial apicid : 0

processor : 1

physical id : 0

siblings : 4

core id : 0

cpu cores : 2

apicid : 1

initial apicid : 1

processor : 2

physical id : 0

siblings : 4

core id : 1

cpu cores : 2

apicid : 2

initial apicid : 2

Intel Core i5-2520M

(2 cores,

Hyper-Threading on)

Page 31: Лекция 5: Многопоточное программирование: часть 1 (Multithreading programming: multi-core processors, CPU affinity, memory ordering)

CPU Topology GNU/Linux (dmidecode)

3131

# dmidecode -t processor

SMBIOS 2.6 present.

Handle 0x0001, DMI type 4, 42 bytes

Processor Information

Socket Designation: CPU

Family: Core i5

Manufacturer: Intel(R) Corporation

ID: A7 06 02 00 FF FB EB BF

Signature: Type 0, Family 6, Model 42, Stepping 7

Flags: ...

Version: Intel(R) Core(TM) i5-2520M CPU @ 2.50GHz

External Clock: 100 MHz

Max Speed: 2500 MHz

Current Speed: 2500 MHz

L1 Cache Handle: 0x0002

L2 Cache Handle: 0x0003

L3 Cache Handle: 0x0004

Asset Tag: None

Part Number: None

Core Count: 2

Core Enabled: 2

Thread Count: 4

Characteristics: 64-bit capable

Page 32: Лекция 5: Многопоточное программирование: часть 1 (Multithreading programming: multi-core processors, CPU affinity, memory ordering)

CPU Topology GNU/Linux (turbostat)

3232

$ ~/linux-3.11.2/tools/power/x86/turbostatcor CPU %c0 GHz TSC SMI %c1 %c3 %c6 %c7 CTMP PTMP %pc2 %pc3 %pc6 %pc7 Pkg_W Cor_W GFX_W

2.37 2.99 2.49 0 97.63 0.00 0.00 0.00 66 68 0.00 0.00 0.00 0.00 13.90 10.65 0.19

0 0 2.59 2.99 2.49 0 97.41 0.00 0.00 0.00 66 68 0.00 0.00 0.00 0.00 13.90 10.65 0.19

0 1 1.14 2.99 2.49 0 98.86

1 2 5.07 2.99 2.49 0 94.93 0.00 0.00 0.00 63

1 3 0.69 2.99 2.49 0 99.31

� turbostat – утилита, входящая в состав ядра Linux,

для отображения топологии процессоров, их текущей частоты

и информации о энергопотреблении (power-state)

� turbostat использует инструкцию CPUID

� Source code: linux/tools/power/x86/turbostat/turbostat.c

Intel Core i5-2520M

(2 cores,

Hyper-Threading on)

Page 33: Лекция 5: Многопоточное программирование: часть 1 (Multithreading programming: multi-core processors, CPU affinity, memory ordering)

CPU Topology GNU/Linux (hwloc)

3333

$ lstopo ./topo.png

� hwloc – пакет, собирающий информацию о топологии процессоров и

кеш-памяти машины

� lstopo – формирует файл (png, pdf, xml) с топологией машины

� lstopo-no-graphics – выводит топологию машины в консоль

http://www.open-mpi.org/projects/hwloc/

Page 34: Лекция 5: Многопоточное программирование: часть 1 (Multithreading programming: multi-core processors, CPU affinity, memory ordering)

CPU Topology GNU/Linux (hwloc)

3434

$ lstopo-no-graphics

Machine (7873MB)

Socket L#0 + L3 L#0 (3072KB)

L2 L#0 (256KB) + L1d L#0 (32KB) + L1i L#0 (32KB) + Core L#0

PU L#0 (P#0)

PU L#1 (P#1)

L2 L#1 (256KB) + L1d L#1 (32KB) + L1i L#1 (32KB) + Core L#1

PU L#2 (P#2)

PU L#3 (P#3)

HostBridge L#0

PCI 8086:0126

GPU L#0 "card0"

GPU L#1 "controlD64"

PCI 8086:1502

Net L#2 "em1"

PCIBridge

PCI 8086:0084

Net L#3 "wlp3s0"

PCI 8086:1c03

Block L#4 "sda"

Intel Core i5-2520M

(2 cores,

Hyper-Threading on)

http://www.open-mpi.org/projects/hwloc/

Page 35: Лекция 5: Многопоточное программирование: часть 1 (Multithreading programming: multi-core processors, CPU affinity, memory ordering)

CPU Topology Microsoft Windows

3535

� Пакет hwloc (Windows build)

� Функции для получения информации о топологии

машины (MSDN)

o GetNumaHighestNodeNumber

o GetProcessAffinityMask

o GetNumaProcessorNode

o GetNumaNodeProcessorMask

� CPUID

Intel 64 Architecture Processor Topology Enumeration //

http://software.intel.com/en-us/articles/intel-64-architecture-processor-

topology-enumeration

Page 36: Лекция 5: Многопоточное программирование: часть 1 (Multithreading programming: multi-core processors, CPU affinity, memory ordering)

Processor affinity (CPU pinning)

3636

� Process affinity (CPU pinning) – это принудительная привязка

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

операционной системы не будет переносить процесс/поток

на другой процессор)

� Причины:

� нежелательная миграция процесса/потока на другой

процессор может привести к неэффективному

использованию кеш-памяти

� выделение памяти с заданного NUMA-узла

(например, только с локального – ближайшего)

� избежание назначения двух потоков на два аппаратных

SMT-потока (Hyper-Threading) одного физического ядра

(для избежание конкуренции за ресурсы конвейера ядра)

Page 37: Лекция 5: Многопоточное программирование: часть 1 (Multithreading programming: multi-core processors, CPU affinity, memory ordering)

GNU/Linux CPU affinity

3737

� taskset – позволяет привязать процесс (новый или

запущенный) к заданным логическим процессорам

3737Core 0

Architectural State 1

(H-T/SMT core)

Core 1

Architectural State 1

(H-T/SMT core)

Architectural State 0

(H-T/SMT core)

dgemm

CPU0 CPU1 CPU2 CPU3

$ taskset –c 2 ./dgemm

Architectural State 0

(H-T/SMT core)

$ taskset –c 0,1,2 ./dgemm # К любому из 3-х CPU

$ taskset –p 1553 # Информация о привязке процесса 1553

pid 1553's current affinity mask: f

Page 38: Лекция 5: Многопоточное программирование: часть 1 (Multithreading programming: multi-core processors, CPU affinity, memory ordering)

GNU/Linux CPU affinity

3838

3838Core 0

Architectural State 1

(H-T/SMT core)

Core 1

Architectural State 1

(H-T/SMT core)

Architectural State 0

(H-T/SMT core)

dgemm

CPU0 CPU1 CPU2 CPU3

$ taskset -c 0 ./dgemm & # Launch 2 process in parallel

$ taskset -c 1 ./dgemm

Elapsed time: 3.503317 sec.

Elapsed time: 3.706128 sec.

Architectural State 0

(H-T/SMT core)

dgemm

Intel Core i5-2520M

Page 39: Лекция 5: Многопоточное программирование: часть 1 (Multithreading programming: multi-core processors, CPU affinity, memory ordering)

GNU/Linux CPU affinity

3939

3939Core 0

Architectural State 1

(H-T/SMT core)

Core 1

Architectural State 1

(H-T/SMT core)

Architectural State 0

(H-T/SMT core)

dgemm

CPU0 CPU1 CPU2 CPU3

$ taskset -c 0 ./dgemm & # Launch 2 process in parallel

$ taskset -c 2 ./dgemm

Elapsed time: 2.310566 sec.

Elapsed time: 2.364204 sec.

Architectural State 0

(H-T/SMT core)

dgemm

Speedup 1.57

$ ./dgemm & # Default pinning (OS scheduler)

$ ./dgemm

Elapsed time: 2.171322 sec.

Elapsed time: 2.168358 sec.

Page 40: Лекция 5: Многопоточное программирование: часть 1 (Multithreading programming: multi-core processors, CPU affinity, memory ordering)

#include <pthread.h>

int pthread_setaffinity_np(pthread_t thread,

size_t cpusetsize, const cpu_set_t *cpuset);

int pthread_getaffinity_np(pthread_t thread,

size_t cpusetsize, cpu_set_t *cpuset);

GNU/Linux CPU affinity

4040

#include <sched.h>

int sched_setaffinity(pid_t pid, size_t cpusetsize,

cpu_set_t *mask);

int sched_getaffinity(pid_t pid, size_t cpusetsize,

cpu_set_t *mask);

int sched_getcpu(void);

int sched_setscheduler(pid_t pid, int policy,

const struct sched_param *param);

Page 41: Лекция 5: Многопоточное программирование: часть 1 (Multithreading programming: multi-core processors, CPU affinity, memory ordering)

GNU/Linux NUMA policy library

4141

� Linux NUMA policy – набор системных вызовов,

библиотек и утилит для управления памятью и процессами

на NUMA-системах

� Системные вызовы:

get_mempolicy(), set_mempolicy(), mbind(), migrate_pages(),

move_pages(), …

� Библиотека libnuma

� Утилиты: numactl, numastat

� NUMA-узлы (nodes): /sys/devices/system/node/nodeX

Page 42: Лекция 5: Многопоточное программирование: часть 1 (Multithreading programming: multi-core processors, CPU affinity, memory ordering)

GNU/Linux NUMA policy library

4242

$ numactl --hardware

available: 1 nodes (0)

node 0 cpus: 0 1 2 3

node 0 size: 7873 MB

node 0 free: 195 MB

node distances:

node 0

0: 10

$ numactl --show # NUMA policy of the current process

policy: default

preferred node: current

physcpubind: 0 1 2 3

cpubind: 0

nodebind: 0

membind: 0

Intel Core i5-2520M

Page 43: Лекция 5: Многопоточное программирование: часть 1 (Multithreading programming: multi-core processors, CPU affinity, memory ordering)

GNU/Linux NUMA policy library

4343

� Привязать процесс (и его дочерние процессы) к процессорам

указанных NUMA-узлов, память выделять только с указанных узлов

$ numactl --cpunodebind=0 --membind=0 ./dgemm

� Привязать процесс (и его дочерние процессы) к логическим

процессорам согласно нумерации поля “processor” файла

/proc/cpuinfo

$ numactl --physcpubind=1 ./dgemm

� Опции numactl:

o --localalloc – выделять память только с локального

NUMA-узла

o --preferred=node – выделять память с узла node,

если невозможно, выделить с других узлов

o --interleave=nodes – выделяет память с указанных NUMA-узлов

в режиме чередования страниц (interleave)

Page 44: Лекция 5: Многопоточное программирование: часть 1 (Multithreading programming: multi-core processors, CPU affinity, memory ordering)

GNU/Linux libnuma API

4444

#include <numa.h>

/* cc ... –lnuma */

int numa_available(void);

void numa_bind(struct bitmask *nodemask);

int numa_run_on_node_mask(struct bitmask *nodemask);

int numa_sched_setaffinity(pid_t pid, struct bitmask *mask);

void numa_set_preferred(int node);

void numa_set_interleave_mask(struct bitmask *nodemask);

void numa_set_localalloc(void);

void numa_set_membind(struct bitmask *nodemask);

/* ... */

� A NUMA API for LINUX //

http://developer.amd.com/wordpress/media/2012/10/LibNUMA-WP-fv1.pdf

Page 45: Лекция 5: Многопоточное программирование: часть 1 (Multithreading programming: multi-core processors, CPU affinity, memory ordering)

Microsoft Windows CPU Affinity

4545

� Windows Task Manager -> Processes -> Set Affinity…

� Microsoft Windows 7, 8, Vista

C:\> start /affinity 3 dgemm.exe

// C++

BOOL WINAPI SetProcessAffinityMask(_In_ HANDLE hProcess,

_In_ DWORD_PTR dwProcessAffinityMask );

DWORD_PTR WINAPI SetThreadAffinityMask(_In_ HANDLE hThread,

_In_ DWORD_PTR dwThreadAffinityMask );

// C#

public static extern bool

SetProcessAffinityMask(SafeProcessHandle handle, IntPtr mask);

public static extern IntPtr

SetThreadAffinityMask(SafeThreadHandle handle, HandleRef mask);

Page 46: Лекция 5: Многопоточное программирование: часть 1 (Multithreading programming: multi-core processors, CPU affinity, memory ordering)

Microsoft Windows CPU Affinity

4646

// Windows NUMA API

BOOL WINAPI GetNumaProcessorNode(_In_ UCHAR Processor,

_Out_ PUCHAR NodeNumber);

BOOL WINAPI GetNumaNodeProcessorMask(_In_ UCHAR Node,

_Out_ PULONGLONG ProcessorMask);

BOOL WINAPI GetNumaAvailableMemoryNode(_In_ UCHAR Node,

_Out_ PULONGLONG AvailableBytes);

LPVOID WINAPI VirtualAllocExNuma(_In_ HANDLE hProcess,

_In_opt_ LPVOID lpAddress, _In_ SIZE_T dwSize,

_In_ DWORD flAllocationType,

_In_ DWORD flProtect, _In_ DWORD nndPreferred);

/* ... */

� MSDN NUMA Support //

http://msdn.microsoft.com/en-us/library/windows/desktop/aa363804(v=vs.85).aspx

Page 47: Лекция 5: Многопоточное программирование: часть 1 (Multithreading programming: multi-core processors, CPU affinity, memory ordering)

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

4747Hardware (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 48: Лекция 5: Многопоточное программирование: часть 1 (Multithreading programming: multi-core processors, CPU affinity, memory ordering)

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

4848Hardware (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� Операционная система обеспечивает поддержку процессов и потоков уровня

ядра (kernel threads)

� Планировщик реализует алгоритм распределения процессорного времени

между потоками/процессами

� Пользователь создает/уничтожает потоки/процессы через интерфейс

системных вызовов (system calls)

Page 49: Лекция 5: Многопоточное программирование: часть 1 (Multithreading programming: multi-core processors, CPU affinity, memory ordering)

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

4949Hardware (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

� Системные библиотеки (Pthreads, .NET Threads, Apple Cocoa) используют

системные вызовы и реализуют более высокоуровневое API для работы

с потоками

� В системных библиотеках принимается решение как отображать

user-space-потоки в kernel-space-потоки: one-to-one mapping (GNU/Linux, Windows),

one-to-many, many-to-many, many-to-one

Page 50: Лекция 5: Многопоточное программирование: часть 1 (Multithreading programming: multi-core processors, CPU affinity, memory ordering)

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

50Hardware (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

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

реализовывать на базе потоков системных библиотек (POSIX Pthreads,

Windows Threads) легковесные потоки – задачи (tasks, lightweight threads)

� Причины: сокращение издержек, связанных с созданием потоков,

поддержанием их функционирования и переключением контекстов

� Примеры: задачи в OpenMP (#pragma omp task),

Intel TBB (task_group::run), Intel Cilk Plus (cilk_spawn),

� Примеры: библиотеки легковесных user-level-потоков

Qthread, MassiveThreads

� Виртуальные машины и интерпретаторы некоторых языков реализуют

user-level-потоки (green threads): Haskell, Go, Lua, Ruby < v1.9

User-level

threads

(tasks)

System

library

threads(pthreads,

Win32 threads)

Kernel

threads

50

Page 51: Лекция 5: Многопоточное программирование: часть 1 (Multithreading programming: multi-core processors, CPU affinity, memory ordering)

Процессы и потоки

5151

Инструкции

(Instructions)

Инициализированные данные

(Initialized data)

ELF/PE File

� Исполняемый файл (Image) на диске – программа (Application, Program)

� Запущенная программа – процесс (Process) с одним потоком выполнения

Memory

Инструкции

(Instructions)

Инициализированные данные

(Initialized data)

Неинициализированные данные

(Uninitialized data)

Куча (Heap – Virtual Memory)

Данные библиотек

(Library data)

Инструкции библиотек

(Library instructions)

Stack

Registers

Поток 0

(Thread 0)

Page 52: Лекция 5: Многопоточное программирование: часть 1 (Multithreading programming: multi-core processors, CPU affinity, memory ordering)

Многопоточный процесс (Multithreaded)

5252

Memory

Инструкции

(Instructions)

Инициализированные данные

(Initialized data)

Неинициализированные данные

(Uninitialized data)

Куча (Heap – Virtual Memory)

Данные библиотек

(Library data)

Инструкции библиотек

(Library instructions)

Stack

Registers

Поток 0

(Thread 0)

Stack

Registers

Поток 1

(Thread 1)

Stack

Registers

Поток 2

(Thread 2)

Stack

Registers

Поток 3

(Thread 3)

Stack

Registers

Поток 4

(Thread 4)

Stack

Registers

Поток 5

(Thread 5)

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

архитектурных регистров при переключении контекстов (context switching)

� Куча процесса, инструкции, статические данные (инициализированные)

общие для всех потоков

Page 53: Лекция 5: Многопоточное программирование: часть 1 (Multithreading programming: multi-core processors, CPU affinity, memory ordering)

Main memory

Multiprocess vs. Multithreaded program

5353

� Однопоточный процесс обращается к памяти

Cache

Thread 0

Heap

Virtual addr. v[0] TLB

v[0], v[1], v[2]

// Mem -> Reg

movl v[0], %eax

Physical Addr. v[0]

Physical addr. v[0]

� Главный поток процесса обращается

к элементу массива v[0] в его памяти (куче)

� Виртуальный адрес v[0] преобразуется

в физический: находится запись

в кеш-памяти TLB или при помощи ядра

� По физическому адресу данный загружаются

из кеш-памяти или оперативной памяти

в регистр

Process

Page 54: Лекция 5: Многопоточное программирование: часть 1 (Multithreading programming: multi-core processors, CPU affinity, memory ordering)

Main memory

Multiprocess vs. Multithreaded program

5454

Многопоточная программа (Multithreaded application)

Cache

Thread 0

Heap

Virtual addr. v[0] TLB

v[0], v[1], v[2]

Physical Addr. v[0]

V[0] Proc1

Physical addr. v[0]

Thread 1

Process � Запустили процесс с двумя потоками,

оба потока читают v[0]

� Виртуальные адреса v[0] в обеих потоках

совпадают – потоки разделяют общую память

� Физические адреса v[0] в каждом потоке также

совпадают, страницы памяти выделяются

процессу и совместно используются потокамиProcess 1

Page 55: Лекция 5: Многопоточное программирование: часть 1 (Multithreading programming: multi-core processors, CPU affinity, memory ordering)

Main memory

Multiprocess vs. Multithreaded program

5555

Многопроцессная программа (Multi-process application)

Cache

Thread 0

Heap

Virtual addr. v[0] TLB

v[0], v[1], v[2]

Physical Addr. v[0]

V[0] Proc1

Physical addr. v[0]

� Запустили 2 процесса одной и той же

программы, оба процесса читают v[0]

� Виртуальный адрес v[0]

в обеих процессах совпадает

� Физический адрес v[0] в каждом процессе

свой, т.к. процессам выделены разные

страницы памяти

� Данные каждого процесса будут занимать

местов в TLB, кеш-памяти

Thread 0

Heap

v[0], v[1], v[2]

Process 1 Process 2

V[0] Proc2

Page 56: Лекция 5: Многопоточное программирование: часть 1 (Multithreading programming: multi-core processors, CPU affinity, memory ordering)

Main memory

Multiprocess vs. Multithreaded program

5656

Многопроцессная программа (Multi-process application)

Cache

Thread 0

Heap

Virtual addr. v[0] TLB

v[0], v[1], v[2]

Physical Addr. v[0]

V[0] Proc1

Physical addr. v[0]

Выводы

� Многопроцессная версия программы будет

оказывать большую нагрузку

на TLB и кеш-память

� В многопоточной программе отказ одного

потока может привезти к отказу всего

приложения

Архитектуру приложения следует

выбирать под решаемую задачу

Thread 0

Heap

v[0], v[1], v[2]

Process 1 Process 2

V[0] Proc2

Page 57: Лекция 5: Многопоточное программирование: часть 1 (Multithreading programming: multi-core processors, CPU affinity, memory ordering)

Memory consistency

5757

� В ходе выполнения инструкций на суперскалярном процессоре операции

чтения и записи памяти могут быть выполнены в порядке отличном

от исходного (out of order execution)

� Процессор реализует одну из моделей согласованности памяти

(Memory consistency):

� Sequential consistency – операции чтения и записи

не переупорядочиваются (strict memory ordering)

� Relaxed consistency – допустимы некоторые виды переупорядочивания

o Loads can be reordered after loads

o Loads can be reordered after stores

o Stores can be reordered after stores

o Stores can be reordered after loads

� Weak consistency (strict memory ordering) – допустимо любое

переупорядочивание операций чтения и записи; для предотвращения

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

“барьер памяти” (memory barrier, membar, memory fence)

Page 58: Лекция 5: Многопоточное программирование: часть 1 (Multithreading programming: multi-core processors, CPU affinity, memory ordering)

Memory ordering

58

Type Alpha ARMv7 POWERSPARC

PSOx86 x86 oostore AMD64 IA-64 zSeries

Loads reordered

after loadsY Y Y Y Y

Loads reordered

after storesY Y Y Y Y

Stores reordered

after storesY Y Y Y Y Y

Stores reordered

after loadsY Y Y Y Y Y Y Y Y

Atomic reordered

with loadsY Y Y Y

Atomic reordered

with storesY Y Y Y Y

Dependent loads

reorderedY

Incoherent

Instruction cache

pipelineY Y Y Y Y Y Y Y

58

Page 59: Лекция 5: Многопоточное программирование: часть 1 (Multithreading programming: multi-core processors, CPU affinity, memory ordering)

Memory ordering Intel64 (Core 2 Duo)

5959

Chapter 8.2 [1]: In a single-processor system for memory regions defined as write-back

cacheable, the memory-ordering model respects the following principles:

� Reads are not reordered with other reads.

� Writes are not reordered with older reads.

� Writes to memory are not reordered with other writes, with the following exceptions: writes

executed with the CLFLUSH instruction; streaming stores (writes) executed with the non

temporal move instructions (MOVNTI, MOVNTQ, MOVNTDQ, MOVNTPS, and

MOVNTPD); and string operations (see Section 8.2.4.1).

� Reads may be reordered with older writes to different locations but not with older writes to

the same location.

� Reads or writes cannot be reordered with I/O instructions, locked instructions, or serializing

instructions.

� Reads cannot pass earlier LFENCE and MFENCE instructions.

� Writes cannot pass earlier LFENCE, SFENCE, and MFENCE instructions.

� LFENCE instructions cannot pass earlier reads.

� SFENCE instructions cannot pass earlier writes.

� MFENCE instructions cannot pass earlier reads or writes.

[1] Intel® 64 and IA-32 Architectures Software Developer's Manual Combined Volumes 3A, 3B, and 3C:

System Programming Guide // http://download.intel.com/products/processor/manual/325384.pdf

Page 60: Лекция 5: Многопоточное программирование: часть 1 (Multithreading programming: multi-core processors, CPU affinity, memory ordering)

Weak memory ordering

6060

� Имеется переменная count, доступ к которой защищён через lock

(критическая секция)

� Увеличиваем count и освобождаем lock (lock = 0)

/* Считаем, что lock уже захвачен */

movl count, %eax

incl %eax

movl %eax, count

movl $0, lock

� На суперскалярном процессоре со слабым упорядочиванием доступа к памяти

(weak ordering of memory) две последние инструкции могут быть

переставлены и выполнены в следующем порядке:

1. movl count, %eax

2. incl %eax

3. movl $0, lock

4. movl %eax, count

� lock будет освобожден прежде чем в count будет записано новое значение,

другой поток может захватить lock и успеть загрузить старое значение count

Программист должен учитывать реализуемую процессором модель

упорядочивания доступа к памяти (memory ordering)

Page 61: Лекция 5: Многопоточное программирование: часть 1 (Multithreading programming: multi-core processors, CPU affinity, memory ordering)

Weak memory ordering

6161

1. movl count, %eax

2. incl %eax

3. movl $0, lock

4. movl %eax, count

� Решение – запретить процессору переставлять две последние

инструкции movl

/* Считаем, что lock уже захвачен */

movl count, %eax

incl %eax

movl %eax, count

mfence /* ждем пока все операции load/store завершатся */

movl $0, lock

� mfence – это инструкция “барьер памяти” (memory barrier)

гарантирует, что пока не завершатся предшествующие операции

load/store новые операции load/store не будут выполнены

� mfence – performs a serializing operation on all load and store instructions

that were issued prior the MFENCE instruction [Intel docs]

Page 62: Лекция 5: Многопоточное программирование: часть 1 (Multithreading programming: multi-core processors, CPU affinity, memory ordering)

/* x86, x86_64 */

void _mm_lfence(); /* lfence */

void _mm_sfence(); /* sfence */

void _mm_mfence(); /* mfence */

Memory barrier

6262

� Compiler memory barrier – предотвращает перестановку инструкций

компилятором (в ходе оптимизации)

/* GNU inline assembler */

asm volatile("" ::: "memory");

/* Intel C++ intrinsic */

__memory_barrier();

/* Microsoft Visual C++ */

_ReadWriteBarrier()

� Hardware memory barrier – предотвращает перестановку инструкций

процессором

� GCC: Built-in functions for atomic memory access //

http://gcc.gnu.org/onlinedocs/gcc-4.6.2/gcc/Atomic-Builtins.html

� LLVM Atomic Instructions and Concurrency Guide // http://llvm.org/docs/Atomics.html

� Linux kernel memory barriers // https://www.kernel.org/doc/Documentation/memory-barriers.txt

Page 63: Лекция 5: Многопоточное программирование: часть 1 (Multithreading programming: multi-core processors, CPU affinity, memory ordering)

Модели параллельного программирования

6363

� Модели параллельного программирования (Parallel programming models)

можно классифицировать по двум признакам:

1) по способу взаимодействия процессов/потоков (process interaction)

2) по методу декомпозиции задачи, способу выражения параллелизма

(problem decomposition)

Parallel programming models

Process interaction Problem decomposition

Shared memory(PRAM)

Message passing(BSP, LogP, LogGP) Implicit

parallelism

Task parallelism

Data parallelism

Page 64: Лекция 5: Многопоточное программирование: часть 1 (Multithreading programming: multi-core processors, CPU affinity, memory ordering)

Модели параллельного программирования

6464

Problem decomposition

Task parallelism

� Язык/библиотека поддерживает

конструкции для порождения

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

� POSIX Pthreads

� Windows Threads

� OpenMP

� Intel Cilk Plus

� Intel TBB

� Boost Threads

� Microsoft Task Parallel Library, …

POSIX Pthreads:

Data parallelism

� Язык/библиотека реализует параллельные

операции над данными (например,

суммирование элементов массива)

� Intel Array Building Blocks

� Intel Threading Building Blocks

� Intel Cilk/C/C++ Array Notations

� Microsoft Task Parallel Library

� JVM Ateji PX, …

Intel Array Building Blocks:

// Create thread

pthread_create(&tid, 0, fun, 0);

// Sum arrays in parallel

dense<f32> A = B + C;

Page 65: Лекция 5: Многопоточное программирование: часть 1 (Multithreading programming: multi-core processors, CPU affinity, memory ordering)

Fork-join parallelism

6565

� Fork-join – это разновидность параллелизма задач, которая поддерживает две

операции для динамического порождения задачи и ожидания их завершения:

� fork – динамически порождает новую задачу (поток), которая выполняется

параллельно с родительской задачей

� join – дожидается завершения дочерней задачи, объединяет (join) потоки

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

� Как правило, задачи реализуется на базе

легковесных потоков, которые динамически

распределяются runtime-системой языка/библиотеки

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

� Для динамическая балансировка загрузки потоков

используется алгоритмы типа work stealing

� Fork-join используется для распараллеливания

рекурсивных алгоритмов типа “Divide & Conquer”

� Реализации: OpenMP (tasks), Intel Cilk Plus,

Microsoft Task Parallel Library, …

int fib(int n) {

int x, y;

if (n < 2) return n;

x = cilk_spawn fib(n-1);

y = fib(n-2);

cilk_sync;

return x + y;

}

fib(n-2) fib(n-1)

cilk_sync

cilk_spawn

Page 66: Лекция 5: Многопоточное программирование: часть 1 (Multithreading programming: multi-core processors, CPU affinity, memory ordering)

Конструкции многопоточного программирования

6666

� Конструкции управления потоками

o порождение потоков (create, spawn, fork, run, …)

o ожидание завершения потоков (join, sync, wait, …)

o управление потоками (set_attr, …)

� Конструкции синхронизации потоков (synchronization)

o Критические секции (critical sections)

o Семафоры (semaphores)

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

o Блокировки (locks, spin locks, read-write locks)

o Барьеры (barriers)

o Атомарные операции (atomics, lock-free code)

� Конструкции для взаимодействия потоков (communications)

o Условные переменные (conditional variables)

o “Барьеры памяти” (memory barriers, memory fences)

o Доступ к локальной памяти потоков (thread local storage)

Page 67: Лекция 5: Многопоточное программирование: часть 1 (Multithreading programming: multi-core processors, CPU affinity, memory ordering)

Ссылки

6767

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

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