GraalVM Native Image atende RISC-V
Agora é possível usar GraalVM Native Image no RISC-V! Vou explicar aqui como compilar aplicações para RISC-V e a implementação. Por padrão, o Native Image usa o compilador Graal para produzir código de máquina, mas pode usar o compilador LLVM ao habilitar o backend LLVM ( documentação ). Uma das principais razões para usar o LLVM é que ele oferece suporte a uma ampla variedade de arquiteturas, o que significa que não precisamos implementar o compilador Graal para elas, que é a etapa mais difícil ao adicionar suporte a uma nova arquitetura. Para demonstrar isso, adaptei o back-end Native Image LLVM para máquinas RISC-V no Linux com um GraalVM dev build .
RISC-V
RISC-V é uma arquitetura de conjunto de instruções (ISA) de código aberto criada em 2010. A principal diferença entre essa arquitetura e as atuais líderes de mercado é o fato de o RISC-V ser de código aberto. Embora seu primeiro uso pretendido fosse para pesquisa e educação, o interesse da indústria agora está crescendo.
Ele usa um ISA inteiro de base simples, que evita o ajuste excessivo de padrões de microarquitetura específicos e recursos superotimizados projetados para domínios específicos, reduzindo custos e melhorando o desempenho para tarefas mais diretas. Para usos mais complexos, extensões podem ser adicionadas ao ISA base, como suporte para multiplicação, pontos flutuantes, vetores e muito mais. Algumas dessas extensões são predefinidas, mas também podem ser personalizadas.
Demonstração do Micronauta
Para mostrar a diferença de performance entre rodar na JVM e Native Image, fizemos uma demonstração baseada em uma aplicação Micronaut, um pequeno servidor web, em um emulador RISC-V. As fontes de demonstração podem ser encontradas aqui .
Inicialização do servidor Micronaut usando um aplicativo compilado com Native Image:
__ __ _ _
| \/ (_) ___ _ __ ___ _ __ __ _ _ _| |_
| |\/| | |/ __| '__/ _ \| '_ \ / _` | | | | __|
| | | | | (__| | | (_) | | | | (_| | |_| | |_
|_| |_|_|\___|_| \___/|_| |_|\__,_|\__,_|\__|
Micronaut (v3.6.0)
16:52:29.965 [main] INFO io.micronaut.runtime.Micronaut - Startup completed in 305ms. Server Running: http://fedora-riscv:8080
Binários de compilação cruzada para RISC-V com o back-end LLVM
Considerando que a maioria das formas atuais de executar o Linux em uma máquina RISC-V são lentas, é aconselhável fazer a compilação cruzada dos binários para RISC-V. O Native Image é compatível com alguns pré-requisitos.
Cadeia de ferramentas RISC-V com zlib
A cadeia de ferramentas RISC-V deve ser fornecida ao Native Image. Pode ser encontrado aqui . As versões de gcce glibcprecisam ser as mesmas ou mais antigas que as usadas pela máquina RISC-V.
zlibestá incluído na cadeia de ferramentas RISC-V, mas deve ser compilado manualmente usando o arquivo riscv-gcc. A biblioteca produzida libz.adeve ser movida para path/to/built/toolchain/sysroot/usr/lib/.
CAPCaches e bibliotecas estáticas
Os CAPCaches são informações sobre os intrínsecos C na arquitetura de destino, bem como os valores dos recursos e sinalizadores da CPU. Eles podem ser baixados aqui .
Native Image precisa de bibliotecas estáticas Java e Graal. Eles podem ser baixados aqui .
Procedimento para a construção cruzada de um binário
O procedimento a seguir descreve como construir um binário a partir de um HelloWorld.javaarquivo simples.
O primeiro passo é atender aos pré-requisitos mencionados acima.
Em seguida, baixe uma compilação dev do GraalVM junto com a imagem nativa.
Por fim, execute os seguintes comandos:
$JAVA_HOME/bin/javac Helloworld.java
$JAVA_HOME/bin/native-image HelloWorld -H:CompilerBackend=llvm \
-Dsvm.targetPlatformArch=riscv64 -H:CAPCacheDir=/path/to/capcache \
-H:CCompilerPath=/path/to/riscv-gcc -H:CustomLD=/path/to/riscv-ld \
-H:CLibraryPath=/path/to/static-libraries \
--add-exports=jdk.internal.vm.ci/jdk.vm.ci.riscv64=org.graalvm.nativeimage.builder
-Dsvm.targetPlatformArch=riscv64permite especificar a arquitetura de destino.-H:CompilerBackend=llvmespecifica que usamos o back-end LLVM.-H:CAPCacheDir=/path/to/capcachefornece os CAPCaches pré-computados para a imagem nativa.-H:CCompilerPath=/path/to/riscv-gccfornecegccda cadeia de ferramentas RISC-V para a imagem nativa.-H:CustomLD=/path/to/riscv-ldforneceldda cadeia de ferramentas RISC-V para a imagem nativa.-H:CLibraryPath=/path/to/static-librariesfornece as bibliotecas estáticas para a imagem nativa.
Calcular CAPCaches e compilar bibliotecas estáticas manualmente
Para obter os CAPCaches ou as bibliotecas estáticas manualmente, uma solução é construir uma imagem nativa no RISC-V a partir do código-fonte. Isso pode ser feito usando os seguintes comandos.
git clone https://github.com/oracle/graal.git
git clone https://github.com/graalvm/mx.git
export PATH=$PWD/mx:$PATH
cd graal/substratevm
mx fetch-jdk
# Choose one of the jdk version and run the provided export command
export SKIP_LIBRARIES=true
mx build
Para calcular os CAPCaches, execute o seguinte comando.
$JAVA_HOME/bin/native-image HelloWorld -H:CompilerBackend=llvm \
-H:+ExitAfterCAPCache -H:CAPCacheDir=/path/to/capcache -H:+NewCAPCache \
-add-exports=jdk.internal.vm.ci/jdk.vm.ci.riscv64=org.graalvm.nativeimage.builder
Crie um binário RISC-V nativamente
Embora seja recomendado construir binários cruzados, ainda é possível construí-los em uma máquina RISC-V. O procedimento é muito semelhante ao cross-building. A cadeia de ferramentas não é mais necessária, pois será a nativa, e os CAPCaches e as bibliotecas estáticas serão fornecidos automaticamente. A última diferença está no comando final:
$JAVA_HOME/bin/native-image HelloWorld -H:CompilerBackend=llvm \
--add-exports=jdk.internal.vm.ci/jdk.vm.ci.riscv64=org.graalvm.nativeimage.builder
Para adicionar o alvo RISC-V à Imagem Nativa, tivemos que implementar todas as mudanças descritas na documentação . No entanto, existem algumas outras alterações não mencionadas relacionadas ao RISC-V.
Implementação JVMCI
O compilador Graal depende da Java Virtual Machine Compiler Interface (JVMCI), o que significa que este subcomponente Java deve ser implementado para usar Native Image, pois depende do compilador Graal. Embora o back-end LLVM não use todo o compilador Graal, ele ainda usa seu front-end e, portanto, precisa de um subconjunto de JVMCI. A implementação deste subconjunto para RISC-V pode ser encontrada aqui .
Conclusão
O backend RISC-V LLVM suporta quase todos os recursos que os outros backends LLVM suportam!
Ainda há trabalho a fazer, como adicionar suporte para macOS e outros sistemas operacionais. Algumas otimizações específicas do alvo podem ser interessantes de investigar, já que o RISC-V fornece alguns registradores específicos que nem todas as outras arquiteturas possuem. Por exemplo, existe o registrador de thread ( x4).
Considerando que levou apenas cerca de seis meses para adicionar suporte RISC-V à imagem nativa usando o back-end LLVM, a ideia de adicionar suporte para outros alvos potenciais, como WebAssembly, é atraente. De fato, adicionar outras arquiteturas se tornará ainda mais acessível, pois o backend LLVM em breve emitirá a própria seção de dados Native Image, permitindo que ele pule a adição de informações sobre arquivos de objeto.
Congratulamo-nos com o seu feedback! Você pode compartilhá-lo via Slack , GitHub , Twitter ou Mastodon .





































![O que é uma lista vinculada, afinal? [Parte 1]](https://post.nghiatu.com/assets/images/m/max/724/1*Xokk6XOjWyIGCBujkJsCzQ.jpeg)