Over the last decades computer architectures have turned from single core computers to multi-core and many-core architectures in order to keep the trend of increasing compute power derived from Moore’s Law alive. With the energy and frequency ceilings hit, manufacturers have introduced accelerators featuring thousands of cores and later specialized accelerator architectures to further increase computational power. This in turn has allowed more demanding software to become commercialized like neural networks and ML algorithms which were not possible before, leading to the AI revolution of modern times. With modern accelerators consuming data of highly parallel applications at increasingly higher speeds, the rate at which data is fed to the processor starts to become significant in the total execution time of a program. For the most popular heterogeneous systems which feature the main memory and accelerators loosely coupled, the main bottleneck of the system becomes the memory (or channel) bandwidth raising again the decades old problem of the “Memory Wall” to the surface. Successful attempts on mitigating the effects of the memory bottleneck have been implemented, with cache hierarchies in the accelerators, kernel fusion/fission or via through production of new hardware with tightly coupled accelerators or high bandwidth channels, but in most commercial systems this bottleneck is caused by the popular PCI bus that handles data movement between the accelerator and the main memory. In this thesis we perform an extensive evaluation of interconnect performance on various systems and showcase that the nominal channel bandwidth is approached only for larger transfers while the bandwidth for small transfers is significantly reduced. Moreover, programming models like CUDA, OpenMP and OpenCL treat multiple data inputs to offloaded workloads separately. As such, in order to reap channel performance, developers using these programming models are required to manually pack data together, something that requires advanced knowledge of channel dynamics. Prior work on optimizing these inefficiencies by automatically packing multiple data transfers into a long efficient transfer has been implemented at the compiler level with notable results. This optimization, though, falls on the problem of correctly initializing data into contiguous addresses in order to allow correct packing with partial solutions already proposed. Nevertheless, this approach is proven to be restrictive especially for approaches using asynchronous processes that allow overlap of communication and computation, commonly implemented to accelerate compute intensive kernels. To avoid the data contiguity problem we instead implement fusion in the runtime layer by exploiting a hidden mechanism in the transfer process. Specifically, in order to transfer data to the accelerator, an initial marshaling of data from virtual memory addresses into contiguous physical ones is required before the data can be transferred. We exploit this mechanism to fuse multiple data inputs in this stage offering a more dynamic and versatile approach than what has been explored in the past. The problem that arises with this approach is that the marshaling of data, originally handled by the accelerator device driver, happens before the actual transfer. Device drivers internally optimize this serial process by segmenting and pipelining marshalling and transfer. We re-design and implement this double buffering approach in the runtime and extend it to support the marshalling of multiple distinct data inputs by treating all inputs partaking in the computation of a kernel as a single fused blob. We segment it to the optimal transfer width and orchestrate the pipelining, approaching the maximum theoretical bus performance, all with complete transparency to the developer.
Negli ultimi decenni, le architetture dei calcolatori sono passate dai sistemi a singolo core a quelli multi-core e many-core, nel tentativo di mantenere vivo l’incremento di performance previsto dalla Legge di Moore. Per superare i limiti imposti dal "power wall", i produttori di "system-on-chip" (SoC) hanno iniziato ad affiancare CPU multi-core ad acceleratori programmabili massivamente paralleli e ad acceleratori specializzati, al fine di incrementare ulteriormente la capacità computazionale del sistema mantenendo alta l’efficienza energetica. Ciò ha permesso il deployment di applicazioni complesse, come le reti neurali e gli algoritmi di apprendimento automatico, dai sistemi di calcolo più grandi al piccolo sistema embedded, dando origine alla rivoluzione dell’intelligenza artificiale dei tempi moderni. Con acceleratori che consumano dati provenienti da applicazioni altamente parallele a velocità sempre maggiori, il ritmo con cui i dati vengono forniti al processore inizia a incidere in modo significativo sul tempo totale di esecuzione di un programma. Nei sistemi eterogenei più diffusi, il principale collo di bottiglia diventa la larghezza di banda del sistema di interconnessione tra la CPU, la memoria principale e gli acceleratori, riportando in primo piano il problema, noto da decenni, della Memory Wall. Negli anni sono stati proposti vari approcci per mitigare gli effetti di questo collo di bottiglia, come l’introduzione di gerarchie di cache negli acceleratori, tecniche di kernel fusion/fission o la realizzazione di nuovi hardware con acceleratori strettamente accoppiati o canali ad alta larghezza di banda. Tuttavia, nella maggior parte dei sistemi commerciali, il principale fattore limitante resta l’interconnessione che gestisce il trasferimento dei dati tra l’acceleratore e la memoria principale. In questa tesi viene presentata un’analisi approfondita delle prestazioni del sistema di interconnessione su diversi sistemi, mostrando come la larghezza di banda nominale del canale venga effettivamente raggiunta solo per trasferimenti di grandi dimensioni, mentre per quelli di piccole dimensioni si osserva una riduzione significativa delle prestazioni. Inoltre, i modelli di programmazione come CUDA, OpenMP e OpenCL trattano separatamente i molteplici input di dati destinati agli acceleratori. Di conseguenza, per sfruttare appieno le prestazioni del canale, gli sviluppatori che utilizzano tali modelli devono raggruppare manualmente i dati, operazione che richiede una conoscenza approfondita dei programmi e della dinamica del canale. Studi precedenti hanno proposto ottimizzazioni per ridurre queste inefficienze tramite l’unione automatica di più trasferimenti di dati in un unico trasferimento, implementata a livello di compilatore, ottenendo risultati rilevanti. Tuttavia, tale approccio si scontra con il problema dell’inizializzazione corretta dei dati in indirizzi contigui, necessaria per consentire una fusione efficace, per il quale sono state proposte solo soluzioni parziali. Inoltre, questa tecnica risulta limitante, specialmente nei contesti che impiegano processi asincroni per sovrapporre comunicazione e calcolo — una strategia comunemente utilizzata per nascondere le alte latenze della memoria principale. In questa tesi l’unione viene approfondito lo studio delle problematiche descritte, esplorando sia soluzioni statiche che dinamiche per la loro gestione. In particolare, una soluzione a runtime sfrutta un’operazione preliminare di marshaling, che consiste nel mappare gli indirizzi virtuali di memoria in indirizzi fisici contigui prima del trasferimento effettivo. Tale meccanismo viene sfruttato per fondere più input di dati in questa fase, offrendo un approccio più dinamico e flessibile rispetto a quelli finora esplorati.
Ottimizzare i trasferimenti dati nei sistemi eterogenei: una visione unificata di tecniche di fusione e separazione statiche e dinamiche
SOTIROPOULOS, Dionysios-Odysseas
2026
Abstract
Over the last decades computer architectures have turned from single core computers to multi-core and many-core architectures in order to keep the trend of increasing compute power derived from Moore’s Law alive. With the energy and frequency ceilings hit, manufacturers have introduced accelerators featuring thousands of cores and later specialized accelerator architectures to further increase computational power. This in turn has allowed more demanding software to become commercialized like neural networks and ML algorithms which were not possible before, leading to the AI revolution of modern times. With modern accelerators consuming data of highly parallel applications at increasingly higher speeds, the rate at which data is fed to the processor starts to become significant in the total execution time of a program. For the most popular heterogeneous systems which feature the main memory and accelerators loosely coupled, the main bottleneck of the system becomes the memory (or channel) bandwidth raising again the decades old problem of the “Memory Wall” to the surface. Successful attempts on mitigating the effects of the memory bottleneck have been implemented, with cache hierarchies in the accelerators, kernel fusion/fission or via through production of new hardware with tightly coupled accelerators or high bandwidth channels, but in most commercial systems this bottleneck is caused by the popular PCI bus that handles data movement between the accelerator and the main memory. In this thesis we perform an extensive evaluation of interconnect performance on various systems and showcase that the nominal channel bandwidth is approached only for larger transfers while the bandwidth for small transfers is significantly reduced. Moreover, programming models like CUDA, OpenMP and OpenCL treat multiple data inputs to offloaded workloads separately. As such, in order to reap channel performance, developers using these programming models are required to manually pack data together, something that requires advanced knowledge of channel dynamics. Prior work on optimizing these inefficiencies by automatically packing multiple data transfers into a long efficient transfer has been implemented at the compiler level with notable results. This optimization, though, falls on the problem of correctly initializing data into contiguous addresses in order to allow correct packing with partial solutions already proposed. Nevertheless, this approach is proven to be restrictive especially for approaches using asynchronous processes that allow overlap of communication and computation, commonly implemented to accelerate compute intensive kernels. To avoid the data contiguity problem we instead implement fusion in the runtime layer by exploiting a hidden mechanism in the transfer process. Specifically, in order to transfer data to the accelerator, an initial marshaling of data from virtual memory addresses into contiguous physical ones is required before the data can be transferred. We exploit this mechanism to fuse multiple data inputs in this stage offering a more dynamic and versatile approach than what has been explored in the past. The problem that arises with this approach is that the marshaling of data, originally handled by the accelerator device driver, happens before the actual transfer. Device drivers internally optimize this serial process by segmenting and pipelining marshalling and transfer. We re-design and implement this double buffering approach in the runtime and extend it to support the marshalling of multiple distinct data inputs by treating all inputs partaking in the computation of a kernel as a single fused blob. We segment it to the optimal transfer width and orchestrate the pipelining, approaching the maximum theoretical bus performance, all with complete transparency to the developer.| File | Dimensione | Formato | |
|---|---|---|---|
|
Sotiropoulos.pdf
accesso aperto
Licenza:
Tutti i diritti riservati
Dimensione
5.8 MB
Formato
Adobe PDF
|
5.8 MB | Adobe PDF | Visualizza/Apri |
I documenti in UNITESI sono protetti da copyright e tutti i diritti sono riservati, salvo diversa indicazione.
https://hdl.handle.net/20.500.14242/381927
URN:NBN:IT:UNIMORE-381927