Dietlibc é uma biblioteca C muito abordada tanto aqui no blog quanto no canal. Por mais que não seja popularmente conhecida, essa é uma biblioteca fortemente utilizada em vários ambientes, especialmente em embarcados assim como a Newlib.
Eu já realizei testes de binários linkados a dietlibc (embutils, minised, runit e muitos outros) e os resultados são surpreendentes. Por esse motivo eu torço para que a dietlibc continue recebendo atenção de várias grupos. A ultima versão lançada da dietlibc foi em 2018 porém, no ultimos dois anos, alguns grupos vem postando tanto patches quanto testes para a biblioteca.
No dia 5 de Janeiro de 2023, Gabriel Ravier enviou um patch com algumas correções no retorno de valores em um recurso chamado wcs{,n}cmp (para near-limits assinado com valores wchar_t). Já no dia 13 de Janeiro do mesmo ano, Jai Arora, Abhishek Rose, Shubhani Gupta e Sorav Bansal da empresa indiana CompilerAI Research GroupIIT reportaram uma série de bugs em funções da dietlibc. A empresa foi tão organizada que disponibilizou códigos fonte em seu próprio repositório no Github e quais flags foram utilizadas durante o processo de compilação para que os bugs possam ser reproduzidos, analisados e assim futuramente corrigidos.
Bessel e ARM na dietlibc
Ficamos um bom tempo sem noticias até que Larry Doolittle, que participa também do desenvolvimento do TinyCC, enviou no final do ano passado dois patches; um com apenas nove linhas e outro com mais sete, para que sejam utilizados nos sub-testes runtests.sh e funcionarem melhor. Sem eles, há certos bugs que fazem com que o shell reclame que cada arquivo dentro de test/*/runtests.sh não seja executável. Outro trabalho que Larry está atuando é na função de Bessel que aponta das versões 12 e 13 do GCC.
"Eu sei algo sobre funções de Bessel, então isso despertou meu interesse e comecei a me aprofundar. Eu aprendi duas coisas principais: bessel.c inclui uma seção escrita somente para x86 e não possui nenhum banco de teste."
Larry criou um tarball de 8 kbyte e postou sem seu site pessoal contendo implementações de código de pesquisa bessel.c reescritos de forma simples e portável. O arquivos pode ser baixado em:
A integridade do arquivo pode ser verificada utilizando sha256sum e confira o resultado a seguir:
18da50d99030c680d1dfa33e2f78e3abf056a2b91a3d530a6b42d1116e8f67a9 diet-bessel-test.tar.gz
Esse código inclui também um banco de teste que podem ser realizados com a opção make -C test e obter os resultados parecidos com os abaixo:
$ make -C test # riscv64make: Entering directory '/redacted/test'gcc -std=c99 -O2 -pedantic -Wall -Wextra -I../include bessel.c ../libm/bessel.c -lm -o bessel./besselBessel function test with sizeof(double) == 8 and sizeof(long double) == 16in 176: J max errors 0.0000000000000021 0.00000000005 0.00000000005 0.0000000009in 175: Y max errors 0.00000000005 0.00000000023 0.000000005 0.000000084max |J| at known zeros 0.00000000002 0.0000016 0.0000011max |Y| at known zeros 0.00000000087 0.0000011 0.0000007Y_0 at first zero 0.00000000327Hankel modulus-squared max error 0.00000000039PASS
$ make -C test # x86_64make: Entering directory '/redacted/test'gcc -std=c99 -O2 -pedantic -Wall -Wextra -I../include bessel.c ../libm/bessel.c -lm -o bessel./besselBessel function test with sizeof(double) == 8 and sizeof(long double) == 16in 176: J max errors 0.0000000000000513 0.00000000005 0.00000000005 0.0000000009in 175: Y max errors 0.00000000005 0.00000000023 0.000000005 0.000000084max |J| at known zeros 0.00000000002 0.0000016 0.0000011max |Y| at known zeros 0.00000000087 0.0000011 0.0000007Y_0 at first zero 0.00000000327Hankel modulus-squared max error 0.00000000039PASS
$ make -C test # armv7l (armhf)make: Entering directory '/redacted/test'gcc -std=c99 -O2 -pedantic -Wall -Wextra -I../include bessel.c ../libm/bessel.c -lm -o bessel./besselBessel function test with sizeof(double) == 8 and sizeof(long double) == 8in 176: J max errors 0.0000000000456691 0.00000000007 0.00000000008 0.0000000009in 175: Y max errors 0.00000000014 0.00000000023 0.000000005 0.000000084max |J| at known zeros 0.00000000002 0.0000016 0.0000011max |Y| at known zeros 0.00000000087 0.0000011 0.0000007Y_0 at first zero 0.00000000327Hankel modulus-squared max error 0.00000000139FAIL
O novo banco de testes é quatro vezes maior e Larry trabalha para concluir a documentação antes de submeter o patch. E por ultimo, Larry reportou um problema que ocorre na dietlibc com a arquitetura ARM quando utilizadas algumas flags. Não se trata de um problema exclusivo na arquitetura ARM, esses erros ocorrem em muitas arquiteturas, menos em x86_64 e x32.
"DEFAULTCFLAGS e seu -nostdinc também é problemático para construir json em qualquer arquitetura exceto em x86_64 and x32... ...gamma.h sofre da mesma codificação específica 387 assim como bessel.c. ... ... Tentar consrtuir código de usuário utilizando quaisquer funções matemática falha, faltando coisas como sin cos exp log, que são definidas em assembly em x86_64 e i386. ..."
Estes são alguns trechos que eu traduzi e que notei que o grande problema é que estes recursos não foram portados para outras arquiteturas. Agora é esperar que as comunidades trabalhem nos problemas. Report já temos.
More working around optimiser bugs (04/07/2024)
Thorsten Glaser da Evolvis informou que a dietlibc entra em um loop interminável na arquitetura arm64 devido o GCC otimizar a implementação da chamada strlen. Uma solução sugerida por Thorsten foi adicionar a opção -ffreestanding na variável DEFAULTCFLAGS (e IMHO bootloaders, kernels e libcs também precisam ser construídas com essa opção) que corrige esse problema.
Nenhum comentário:
Postar um comentário
Viu algum erro e quer compartilhar seu conhecimento? então comente aí.
Observação: somente um membro deste blog pode postar um comentário.