Programovanie

Prečo efektívne paralelné programovanie musí obsahovať škálovateľné pridelenie pamäte

Viacjadrový procesor? Áno.

Napísať program, ktorý má bežať paralelne? Áno.

Pamätali ste si, že ste použili Scalable Memory Allocator? Nie? Potom čítajte ďalej ...

Podľa mojich skúseností je zabezpečenie, aby „alokácia pamäte“ programu bola pripravená na paralelizmus, často prehliadaným prvkom dobrého fungovania paralelného programu. Môžem vám ukázať neuveriteľne ľahký spôsob, ako zistiť, či to nie je problém kompilovaného programu (C, C ++, Fortran atď.) - a tiež ako to napraviť.

Kritickou súčasťou každého paralelného programu je škálovateľné pridelenie pamäte, ktoré zahŕňa použitieNovýako aj explicitné volania na číslomalloc, calloc alebo realloc. Medzi možnosti patria TBBmalloc (Intel Threading Building Blocks), jemalloc a tcmalloc. TBBmalloc má novú funkciu „proxy“, ktorá umožňuje ľahké vyskúšanie na ľubovoľnom kompilovanom programe za menej ako 5 minút.

Výhody výkonu pri použití škálovateľného alokátora pamäte sú značné. TBBmalloc bol medzi prvými široko používanými škálovateľnými alokátormi pamäte, a to nemalou mierou, pretože bol zadarmo s TBB, aby pomohol zdôrazniť dôležitosť zahrnutia úvah o alokácii pamäte do každého paralelného programu. Dnes je stále mimoriadne populárny a stále je jedným z najlepších dostupných alokátorov škálovateľnej pamäte.

Jednoduché riešenie bez akýchkoľvek zmien kódu

Pomocou metód proxy môžeme globálne nahradiť Nový/vymazať a malloc/calloc/realloc/zadarmo/atď. rutiny s technikou výmeny dynamického pamäťového rozhrania. Tento automatický spôsob nahradenia predvolených funkcií pre dynamické prideľovanie pamäte je zďaleka najpopulárnejším spôsobom použitia TBBmalloc. Je to ľahké a postačujúce pre väčšinu programov.

Podrobnosti o mechanizme použitom v každom operačnom systéme sa trochu líšia, ale čistý efekt je všade rovnaký.

Našu 5-minútovú skúšobnú verziu začíname stiahnutím a inštaláciou Threading Building Blocks (bezplatne z //threadingbuildingblocks.org; je zahrnutá aj ako súčasť produktov Intel Parallel Studio).

Použite proxy v systéme Linux

V systéme Linux môžeme vykonať výmenu buď načítaním knižnice proxy v čase načítania programu pomocou LD_PRELOAD premenná prostredia (bez zmeny spustiteľného súboru) alebo prepojením hlavného spustiteľného súboru s knižnicou proxy (-ltbbmalloc_proxy). Zavádzač programov systému Linux musí byť schopný nájsť knižnicu proxy a knižnicu škálovateľného alokátora pamäte v čase načítania programu. Preto môžeme zahrnúť adresár obsahujúci knižnice v priečinku LD_LIBRARY_PATH premennú prostredia alebo do nej pridať /etc/ld.so.conf.

Vyskúšajte nasledovne:

čas ./a.out (alebo ako sa volá náš program)

export LD_PRELOAD = libtbbmalloc_proxy.so.2

čas ./a.out (alebo ako sa volá náš program)

Použite proxy v systéme macOS

V systéme macOS môžeme výmenu vykonať buď načítaním knižnice proxy v čase načítania programu pomocou nástroja DYLD_INSERT_LIBRARIES premenná prostredia (bez zmeny spustiteľného súboru) alebo prepojením hlavného spustiteľného súboru s knižnicou proxy (-ltbbmalloc_proxy). Zavádzač programu macOS musí byť schopný nájsť proxy knižnicu a knižnicu škálovateľného alokátora pamäte v čase načítania programu. Na tento účel môžeme zahrnúť adresár obsahujúci knižnice v priečinku DYLD_LIBRARY_PATH premenná prostredia.

Vyskúšajte nasledovne:

čas ./a.out (alebo ako sa volá náš program)

exportovať DYLD_INSERT_LIBRARIES = $ TBBROOT / lib / libtbbmalloc_proxy.dylib

čas ./a.out (alebo ako sa volá náš program)

Použite proxy v systéme Windows

V systéme Windows musíme upraviť náš spustiteľný súbor. Môžeme buď vynútiť načítanie proxy knižnice pridaním #include "tbb / tbbmalloc_proxy.h" v našom zdrojovom kóde alebo pomocou určitých možností linkera pri vytváraní spustiteľného súboru:

Pre win32:

            tbbmalloc_proxy.lib / INCLUDE: "___ TBB_malloc_proxy"

Pre win64:

            tbbmalloc_proxy.lib / INCLUDE: "__ TBB_malloc_proxy"

Zavádzač programov Windows musí byť schopný nájsť knižnicu proxy a knižnicu škálovateľného prideľovača pamäte v čase načítania programu. Na tento účel môžeme zahrnúť adresár obsahujúci knižnice v priečinku CESTA premenná prostredia. Vyskúšajte to pomocou programu Visual Studio „Performance Profiler“ na načasovanie programu s alebo bez možnosti zahrnutia alebo prepojenia.

Testovanie používania našej proxy knižnice pomocou malého programu

Odporúčam vám vyskúšať si svoj vlastný program, ako je popísané vyššie. Behajte s proxy serverom a bez neho a uvidíte, aký prínos získa vaša aplikácia. Aplikácie s veľkým počtom paralelizácií a veľkým počtom alokácií pamäte často zaznamenajú zvýšenie o 10 - 20% (tiež som raz videl zvýšenie o 400%), zatiaľ čo programy s malou paralelnosťou alebo malým počtom alokácií nemusia vidieť žiadny účinok. Vyššie popísané rýchle testy s knižnicou proxy vám povedia, v ktorej kategórii sa vaša aplikácia nachádza.

Napísal som tiež krátky program na ilustráciu efektov a na uľahčenie kontroly toho, či sú veci nainštalované a fungujú podľa očakávaní. Knižnicu proxy môžeme vyskúšať pomocou jednoduchého programu:

#include

#include "tbb / tbb.h"

pomocou menného priestoru tbb;

konštanta N = 10 000 000;

int main () {

dvojitý * a [N];

parallel_for (0, N-1, [&] (int i) {a [i] = nové dvojité;});

parallel_for (0, N-1, [&] (int i) {delete a [i];});

návrat 0;

}

Môj ukážkový program využíva veľa miesta v zásobníku, takže “ulimit - je neobmedzený„(Linux / macOS) alebo„/ STACK: 10000000„(Visual Studio: Vlastnosti> Vlastnosti konfigurácie> Linker> Systém> Veľkosť rezervy zásobníka) bude dôležité, aby sa zabránilo okamžitým zlyhaniam.

Po kompilácii sú rôzne spôsoby, ako som spustil svoj malý program a sledoval rýchlosť s knižnicou proxy aj bez nej.

Beh a načasovanie tbb_mem.cpp na štvorjadri virtuálne Stroj Linux, videl som nasledovné:

% času ./tbb_mem

skutočných 0 mil

používateľ 0m0.072s

sys 0m0.048s

%

% exportLD_PRELOAD = $ TBBROOT / lib / libtbbmalloc_proxy.dylib

%

% času ./tbb_mem

skutočné 0m0,043s

používateľ 0m0,048s

sys 0m0.028s

Pri spustení a načasovaní tbb_mem.cpp na štvorjadrovom iMacu (macOS) som videl nasledujúce:

% času ./tbb_mem

skutočné 0m0,046s

používateľ 0m0.078s

sys 0m0.053s

%

% export DYLD_INSERT_LIBRARIES = $ TBBROOT / lib / libtbbmalloc_proxy.dylib

%

% času ./tbb_mem

reálne 0m0,019s

používateľ 0m0.032s

sys 0m0,009s

Vo Windows som pomocou programu Visual Studio „Performance Profiler“ na štvorjadrovej procesoroch Intel NUC (Core i7) videl časy 94ms bez škálovateľného profilovača pamäte a 50ms s ním (pridanie #include "tbb / tbbmalloc_proxy.h"do ukážkového programu).

Úvahy o kompilácii

Osobne som nemal problém s tým, že kompilátory robili „optimalizáciu malloc“, ale technicky by som navrhol, že pri kompilácii s programami by mala byť táto kompilátor „optimalizácia malloc“ zakázaná. Mohlo by byť rozumné skontrolovať dokumentáciu kompilátora vášho obľúbeného kompilátora. Napríklad pri kompilátoroch Intel alebo gcc je najlepšie dodať nasledujúce príznaky:

-fno-builtin-malloc (vo Windows: / Qfno-builtin-malloc)

-fno-builtin-calloc (vo Windows: / Qfno-builtin-calloc)

-fno-builtin-realloc (vo Windows: / Qfno-builtin-realloc)

-fno-builtin-free (vo Windows: / Qfno-builtin-free)

Ak tieto príznaky nepoužijete, nemusí to spôsobiť problém, ale nie je to zlý nápad byť v bezpečí.

Zhrnutie

Použitie škálovateľného alokátora pamäte je základným prvkom každého paralelného programu. Ukázal som, že TBBmalloc je možné ľahko vložiť bez potreby zmien kódu (aj keď pridanie „zahrnutia“ do systému Windows je moje obľúbené riešenie systému Windows). Možno uvidíte pekné zrýchlenie, ktoré trvá len 5 minút práce, a môžete ho ľahko použiť na viac aplikácií. V systémoch Linux a macOS môžete byť dokonca schopní zrýchliť programy bez toho, aby ste mali zdrojový kód!

Kliknite sem a stiahnite si 30-dňovú skúšobnú verziu Intel Parallel Studio XE zadarmo.

$config[zx-auto] not found$config[zx-overlay] not found