Zig vs Fortran para Computação Científica

Introdução

Fortran é a linguagem que praticamente inventou a computação científica. Desde 1957, código Fortran roda simulações climáticas, cálculos de dinâmica de fluidos, astrofísica e engenharia estrutural. Zig, por outro lado, é uma linguagem moderna de sistemas que oferece controle de baixo nível com segurança prática.

A pergunta “Zig pode substituir Fortran para computação científica?” merece uma análise cuidadosa. Este artigo explora onde Zig se destaca e onde Fortran ainda reina. Para outras comparações, veja Zig vs Assembly e Zig vs C Moderno (C23).

Fortran: O Rei da Computação Numérica

Por Que Fortran Persiste

Fortran sobrevive não por inércia, mas porque oferece vantagens genuínas para computação numérica:

  • Arrays multidimensionais nativos: Arrays com múltiplas dimensões são cidadãos de primeira classe
  • Column-major layout: Otimizado para álgebra linear
  • Aliasing rules: O compilador pode assumir que ponteiros não se sobrepõem (como restrict em C)
  • Bibliotecas maduras: LAPACK, BLAS, FFTW, PETSc — décadas de código otimizado
  • Paralelismo integrado: Coarrays e DO CONCURRENT para paralelismo
! Fortran: multiplicação de matrizes nativa
program matmul_exemplo
    real, dimension(1000, 1000) :: A, B, C
    call random_number(A)
    call random_number(B)
    C = matmul(A, B)  ! operação nativa da linguagem
end program

Zig: Controle Moderno para Computação Científica

Vantagens de Zig para HPC

Zig traz ferramentas modernas que Fortran não oferece:

  • SIMD nativo: Tipos vetoriais que compilam para instruções SIMD reais
  • Comptime: Geração de kernels especializados em tempo de compilação
  • Gerenciamento de memória explícito: Controle total sobre alocação e layout
  • Interop com C: Acesso direto a BLAS, LAPACK e qualquer biblioteca C
  • Cross-compilation: Compile para qualquer arquitetura de um único host
const std = @import("std");

// SIMD nativo em Zig
const Vec8f = @Vector(8, f32);

fn dotProductSimd(a: []const f32, b: []const f32) f32 {
    var soma: Vec8f = @splat(0);
    var i: usize = 0;

    while (i + 8 <= a.len) : (i += 8) {
        const va: Vec8f = a[i..][0..8].*;
        const vb: Vec8f = b[i..][0..8].*;
        soma += va * vb;
    }

    var resultado = @reduce(.Add, soma);

    // Processar elementos restantes
    while (i < a.len) : (i += 1) {
        resultado += a[i] * b[i];
    }

    return resultado;
}

Comptime para Kernels Especializados

Uma das maiores vantagens de Zig é gerar código especializado em tempo de compilação:

fn criarKernelConvolucao(comptime tamanho: usize) type {
    return struct {
        kernel: [tamanho][tamanho]f32,

        pub fn aplicar(self: @This(), imagem: []const f32, largura: usize) f32 {
            var soma: f32 = 0;
            inline for (0..tamanho) |dy| {
                inline for (0..tamanho) |dx| {
                    soma += imagem[dy * largura + dx] * self.kernel[dy][dx];
                }
            }
            return soma;
        }
    };
}

// Kernel 3x3 com loops completamente unrolled em compilação
const Gaussian3x3 = criarKernelConvolucao(3);

Comparação Detalhada

Arrays e Dados Numéricos

AspectoZigFortran
Arrays multidimensionaisVia slices e structsNativo, primeira classe
Layout de memóriaRow-major (como C)Column-major
SlicingSuportadoNativo, muito poderoso
BroadcastingManualNativo com operações de array
Operações vetoriaisVia @Vector e loopsNativas (A + B, matmul)

Performance

AspectoZigFortran
SIMDTipos vetoriais nativosAuto-vetorização do compilador
Otimização numéricaLLVM (excelente)GFortran/ifort (excelente)
AliasingNão assume (como C)Assume não-aliasing
Loop unrollingComptime inline forDiretivas do compilador
PrecisãoIEEE 754 estritoPode relaxar com flags

Ecossistema Científico

AspectoZigFortran
BLAS/LAPACKVia @cImportNativo ou via linking
FFTWVia @cImportVia linking
MPIVia @cImportNativo (Fortran MPI bindings)
VisualizaçãoSem bibliotecas nativasLimitado (geralmente via Python)
Machine LearningInexistenteLimitado

Interoperabilidade: O Trunfo de Zig

Zig pode usar todas as bibliotecas C de computação científica diretamente. Isso inclui BLAS, LAPACK, FFTW, HDF5, e qualquer outra biblioteca com interface C:

const c = @cImport({
    @cInclude("cblas.h");
});

fn multiplicarMatrizes(
    A: []const f64,
    B: []const f64,
    C: []f64,
    m: usize,
    n: usize,
    k: usize,
) void {
    c.cblas_dgemm(
        c.CblasRowMajor,
        c.CblasNoTrans,
        c.CblasNoTrans,
        @intCast(m),
        @intCast(n),
        @intCast(k),
        1.0, // alpha
        A.ptr,
        @intCast(k),
        B.ptr,
        @intCast(n),
        0.0, // beta
        C.ptr,
        @intCast(n),
    );
}

Veja Chamar Funções C de Zig e Interoperabilidade C-Zig.

Quando Escolher Cada Uma

Escolha Zig quando:

  • O projeto começar do zero e não tiver legado Fortran
  • Precisar de controle explícito de memória e alocação
  • SIMD manual e kernels otimizados forem necessários
  • Cross-compilation for requisito (embarcados com computação numérica)
  • O projeto misturar computação numérica com I/O, networking ou sistemas
  • Quiser integrar com bibliotecas C existentes

Escolha Fortran quando:

  • Trabalhar com codebases Fortran existentes
  • O domínio for álgebra linear pura, simulações ou CFD
  • A equipe já conhecer Fortran
  • Arrays multidimensionais e operações de array nativos forem essenciais
  • Coarrays e paralelismo integrado forem vantajosos
  • Usar ferramentas HPC que esperam Fortran (MPI Fortran bindings, etc.)

Use ambas quando:

  • Zig como linguagem principal com chamadas a bibliotecas Fortran via C interface
  • Kernels numéricos em Fortran integrados a um sistema maior em Zig
  • Migração gradual de Fortran para Zig

O Futuro

Zig está ganhando tração em nichos onde computação de baixo nível e sistemas se encontram — como IoT com processamento de sinais, firmware com DSP, e servidores de alto desempenho. Fortran continua dominante em simulações científicas tradicionais.

O cenário mais provável é coexistência: Zig para o “glue code” e sistemas ao redor, Fortran para os kernels numéricos já otimizados ao longo de décadas.

Conclusão

Fortran não é uma linguagem ultrapassada — é uma linguagem especializada que continua sendo a melhor escolha para certos domínios de computação científica. Zig não pretende substituir Fortran, mas oferece uma alternativa moderna para novos projetos que combinam computação numérica com programação de sistemas.

Para aprender mais sobre Zig, comece com Introdução ao Zig e explore Arrays Multidimensionais e benchmarking em Zig.

Continue aprendendo Zig

Explore mais tutoriais e artigos em português para dominar a linguagem Zig.