Evaluating Shared Memory Parallel Computing Mechanisms of the Julia Language - Barros, Diana Almeida (2023)
Áreas de estudo como ciência de dados, aprendizado de máquina ou computação científica são áreas promissoras que estão recebendo muitos investimentos atualmente. Essas áreas geralmente são muito complexas e exigem um bom uso dos recursos de computação para um melhor desempenho. Nesse contexto, nasceu a linguagem Julia. Uma linguagem dinâmica que oferece um ambiente de alto desempenho com uma sintaxe amigável. Embora seu design seja voltado para a performance, a computação paralela com memória compartilhada ainda possui alguns recursos em desenvolvimento e os estudos nesta área até o momento são escassos. Neste trabalho, apresentamos um estudo do desempenho dos mecanismos de computação paralela de memória compartilhada da linguagem de programação Julia. Foram analisados o desempenho dos mecanismos Multithreading e SIMD. Na análise do Multithreading, comparamos as estratégias de paralelismo de dados e de tarefas disponíveis através das macros built-in @threads e @spawn, focando na forma como distribuem as iterações do loop. Além do mais, foram analisados os mecanismos de escalonamento de loops disponíveis na versão de Julia utilizada neste trabalho, que são o próprio escalonamento estático da macro @threads e os escalonamentos do pacote FLoops.jl, e foi observado o comportamento da performance de tais mecanismos num ambiente escalável. Na análise dos mecanismos SIMD, comparamos a autovetorização do compilador com a construção built-in @simd e dois pacotes para vetorização. Executamos nossos experimentos com kernels sintéticos, aplicações de benchmarks e em um framework de otimização do mundo real. Nossos resultados mostram que a macro @spawn apresentou melhor desempenho em cargas desbalanceadas e os diferentes tipos de escalonamento de loops oferecidos pelo FLoops.jl ajudam a melhorar a performance das aplicações com desbalanceamento de carga. Contudo, aplicações comuns em cenários reais se mostraram mais suscetíveis a overhead e perda de desempenho justamente pela natureza do problema influenciar na forma em que o código é implementado, sendo mais notáveis quando @spawn é utilizado ou quando o ambiente escala em número de threads. Para os mecanismos SIMD, mostramos que o pacote LoopVectorization.jl proporcionou os melhores resultados de desempenho com baixo esforço de programação.