Rodrigo Kumpera Weblog

Meus achados sobre tecnologia

Lançado Mono 2.2 com estréia de Mono.Simd

January 14th, 2009 · 12 Comments

Acabou de ser lançado versão 2.2 do Mono. Foram vários meses de trabalho e muito suor em corrigir centenas de bugs para podermos fazer nosso melhor release de todos os tempos. Dentro das novidades gostaria de destacar duas relativa ao time que participo. A primeira é o novo JIT baseado em uma representação intermediaria linear, os ganhos de performance podem chegar em até 50% e, também importante, o código do JIT ficou muito mais simples e extensível. A segunda novidade, resultado da maior flexibilidade do mono, é a disponibilização preliminar da biblioteca Mono.Simd, que permite usar a unidade vetorial de processadores modernos.

A impossibilidade utilizar a unidade vetorial a partir de linguagens gerenciadas sempre foi uma das principais críticas dos desenvolvedores C e C++ sob a viabilidade em utilizá-las para código rico em calculo matemático. Isso agora é passado e usando mono e C# é possível gerar código com de alta performance similar ao possível com linguagens de baixo nível.

Para se ter uma ideia das possibilidades, um simples exemplo que transforma uma série de vetores com uma mesma matriz chega a ser 3x mais rápido usando Mono.Simd que o código não vetorial em C, Java ou C#. Isso sem perder as vantagens de se utilizar uma linguagem de alto nível e segura. Mas vamos ao código:

//Primeiro transformação usando ponto flutuante normal
    public static void Transform (ref Matrix matrix, ref Vector vector, ref Vector result)
    {
        result.x = vector.x * matrix.m00 + vector.y * matrix.m01 + vector.z * matrix.m02 + vector.w * matrix.m03;
        result.y = vector.x * matrix.m10 + vector.y * matrix.m11 + vector.z * matrix.m12 + vector.w * matrix.m13;
        result.z = vector.x * matrix.m20 + vector.y * matrix.m21 + vector.z * matrix.m22 + vector.w * matrix.m23;
        result.w = vector.x * matrix.m30 + vector.y * matrix.m31 + vector.z * matrix.m32 + vector.w * matrix.m33;
    }
 
//Agora usando Mono.Simd
    public static void Transform (ref Matrix4f matrix, ref Vector4f vector, ref Vector4f result)
    {
        Vector4f v = vector;
 
        Vector4f r0 = v.Shuffle (ShuffleSel.XFromX | ShuffleSel.YFromX | ShuffleSel.ZFromX | ShuffleSel.WFromX);
        Vector4f r1 = v.Shuffle (ShuffleSel.XFromY | ShuffleSel.YFromY | ShuffleSel.ZFromY | ShuffleSel.WFromY);
        Vector4f r2 = v.Shuffle (ShuffleSel.XFromZ | ShuffleSel.YFromZ | ShuffleSel.ZFromZ | ShuffleSel.WFromZ);
        Vector4f r3 = v.Shuffle (ShuffleSel.XFromW | ShuffleSel.YFromW | ShuffleSel.ZFromW | ShuffleSel.WFromW);
 
        r0 = r0 * matrix.row0;
        r1 = r1 * matrix.row1;
        r2 = r2 * matrix.row2;
        r3 = r3 * matrix.row3;
 
        result = r0 + r1 + r2 + r3;
    }

O código usando Mono.Simd fica um pouco mais complexo, principalmente até se entender como Shuffle e outros combinadores funcionam. Porém quando executado, a versão tradicional precisa executar 16 operações de multiplicação e 12 de soma contra 4 multiplicações 3 somas simd na versão vetorizada. A diferença é clara e o números também.

O release 2.2 foi o resultado de muito esforço pelo time por traz do mono e todos seus contribuidores. Esse release, porém, é especial para mim pois Mono.Simd é resultado de alguns meses de trabalho meu e fiquei muito feliz com a repercussão positiva que recebemos – vários projetos estão estudando como implementar bibliotecas de matemática vetorial usando ela.

Tags: Performance · Programming · mono

12 responses so far ↓

  • 1 Tiago "PacMan" Peczenyj // Jan 15, 2009 at 12:26 am

    Ok, ainda irei entender esse código mas… parabens!

  • 2 Efraim Queiroz // Jan 15, 2009 at 12:45 am

    Parabens!

  • 3 Rod // Jan 20, 2009 at 4:01 pm

    Meus sinceros parabens!!!!
    E que continue sempre contribuindo para o Mono.

  • 4 cristo // Jan 21, 2009 at 10:09 am

    Cara isso é demais, principalmente na possibilidade de usar isso em jogos, ah sim uma pergunta o que está faltando no mono atualmente é uma api mais específica para desenvolvimento RIA (sem ser silverlight, mas algo próprio e mais abrente), com java já fizeram JavaFX, só falta mesmo algo para Mono, mas único.

  • 5 kumpera // Jan 21, 2009 at 10:21 am

    O Moonlight é a alternativa de RIA com mono. Lembrando que por ser software livre, poderá ser usado de forma muito mais ampla e flexivel que o Silverlight.

  • 6 Damiao ( ddamy´s ) // Feb 7, 2009 at 10:12 pm

    Meus parebens, você é show!! Ainda vou entender este código como disse o nosso amigo acima. Vlw!!

  • 7 Tony Alexander Hild // Aug 20, 2009 at 11:55 am

    Olá Rodrigo,

    Parabéns, deve ser muito legal trabalhar no projeto Mono.

    Estou estudando a respeito de programação paralela e resolvi brincar um pouco com o Mono.Simd. Então criei uma classe

    [StructLayout(LayoutKind.Explicit, Pack = 0, Size = 16)]
    public struct Vector3
    {

    [FieldOffset(0)]
    internal float X;
    [FieldOffset(4)]
    internal float Y;
    [FieldOffset(8)]
    internal float Z;
    [FieldOffset(12)]
    private float W;
    }

    que “encapsula” o seu Vector4f.

    Mas, quando habilito a otimização SIMD (-O=simd), mesmo não fazendo nenhuma operação usando os op codes, alguns valores do meu vetor se perdem, e ficam como NaN. Acho que o é algum problema no JIT.

    Se quiser eu posso criar um bug report e criar um caso de testes.

    Falow,

    Tony

  • 8 kumpera // Aug 20, 2009 at 12:13 pm

    Oi Tony.

    Me mande um exemplo completo que mostre o problema ou então simplesmente adicione um bug no tracker do mono: http://tinyurl.com/nrdj8r

    Baseado no seu exemplo não tenho como reproduzir o erro.

  • 9 Tony Alexander Hild // Aug 20, 2009 at 5:48 pm

    Este teste foi realizado no Windows, e no Linux eu realizei outros testes com resultados parecidos. O processador usado no teste tem suporte somente para SSE. Com op_Addition e op_Multiply aceleradas para o Vector4f, mas o Shuffle não é acelerado. Neste teste, o problema ocorreu no Vector4f e não ocorreu na minha estrutura. Este problema ocorre de forma aleatória, e não ocorre quando a otimização está desabilitada.

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using Mono.Simd;
    using System.Runtime.InteropServices;

    namespace SimdBug
    {
    class Program
    {
    static void Main(string[] args)
    {

    Vector4f v1 = new Vector4f(3), v2 = new Vector4f(3);
    Console.WriteLine(v1 * v2);

    v1 = new Vector4f(1, 2, 3, 4);
    v2 = new Vector4f(5, 6, 7, 8);
    Console.WriteLine(v1 * v2);

    Vector3 va = new Vector3(3), vb = new Vector3(3);
    Console.WriteLine(va * vb);

    va = new Vector3(1, 2, 3);
    vb = new Vector3(4, 5, 6);
    Console.WriteLine(va * vb);

    }
    }

    [StructLayout(LayoutKind.Explicit, Pack = 0, Size = 16)]
    public struct Vector3
    {

    [FieldOffset(0)]
    public float X;
    [FieldOffset(4)]
    public float Y;
    [FieldOffset(8)]
    public float Z;
    [FieldOffset(12)]
    public float W;

    public Vector3(float x, float y, float z)
    {
    X = x;
    Y = y;
    Z = z;
    W = 0;
    }

    public Vector3(float f)
    {
    X = f;
    Y = f;
    Z = f;
    W = 0;
    }

    public static Vector3 operator *(Vector3 left, Vector3 right)
    {
    unsafe
    {
    *(Vector4f*)&left *= *(Vector4f*)&right;
    return left;
    }
    }

    public override string ToString()
    {
    return string.Format(”[x:{0}, y:{1}, z:{2}]“, X, Y, Z);
    }

    }
    }

    H:\SimdBug\SimdBug\bin\Debug>mono -O=simd SimdBug.exe

    mono SimdBug.exe

    [x:9, y:9, z:9]
    [x:4, y:10, z:18]

    Mono JIT compiler version 2.4.2.3 (tarball)
    Copyright (C) 2002-2008 Novell, Inc and Contributors. http://www.mono-project.com
    TLS: normal
    GC: Included Boehm (with typed GC)
    SIGSEGV: normal
    Notification: Thread + polling
    Architecture: x86
    Disabled: none

    Obrigado pela atenção,

    Tony

  • 10 Tony Alexander Hild // Aug 20, 2009 at 5:50 pm

    Os resultados do console não foram enviados corretamente.

    H:\SimdBug\SimdBug\bin\Debug>mono -O=simd SimdBug.exe
    [0, 0,01161598, 0, 0]
    [5, 12, ?², ?]
    [x:9, y:9, z:9]
    [x:4, y:10, z:18]

    H:\SimdBug\SimdBug\bin\Debug>mono SimdBug.exe
    [9, 9, 9, 9]
    [5, 12, 21, 32]
    [x:9, y:9, z:9]
    [x:4, y:10, z:18]

  • 11 kumpera // Aug 20, 2009 at 6:02 pm

    Por favor entre com o bug no tracker do mono ou me mande 1 email, pq não consigo reproduzí-lo localmente e fazer troubleshooting pelo compentário de um blog não rola.

  • 12 Tony Alexander Hild // Aug 20, 2009 at 6:38 pm

    Criei um bug report: https://bugzilla.novell.com/show_bug.cgi?id=533079

    Valew

Leave a Comment