Optimizing a C# engine

28
Javier Cantón Ferrero @jcant0n http://geeks.ms/blogs/jcanton/ Optimizando un motor de videojuegos en C#

Transcript of Optimizing a C# engine

Javier Cantón Ferrero

@jcant0n

http://geeks.ms/blogs/jcanton/

Optimizando un motor de videojuegos en C#

Problema 1

Structs

• Objetos con una vida muy corta de tiempo

• Mejor cuando solo trabaja el Stack

• Tener en cuenta el GC

• Usar paso por referencia siempre que sea posible

Stack Heap

p = 0x??????

Stack Heap

p = 0x000000

Stack Heap

p = 0x123456

PlayerName = “Mario”Life = 90

Stack Heap

PlayerName = “Mario”Life = 30

p = 0x123456

value = 30

Stack Heap

PlayerName = “Mario”Life = 30

p = 0x123456

value = 20

Ejemplo

Matrix a, b, cc = Math.Multiply( a, b )

4 bytes / float16 floats / Matrix3 copias

3 * 16 * 4 = 192 bytes

Garbage Collector

• Salta cada vez que el heap crece en un determinado tamaño

4 bytes / float16 floats / Matrix3 copias

3 * 16 * 4 = 192 bytes

1MB = 1048576 bytes1048576 / 192 bytes = 5461,3

5461,3 / 60 fps = 91,02

Profiler

private void UpdateMatrices(Matrix world0, Matrix view0, Matrix projection0,Matrix world1, Matrix view1, Matrix projection1,Matrix world2, Matrix view2, Matrix projection2,Matrix world3, Matrix view3, Matrix projection3,Matrix world4, Matrix view4, Matrix projection4,

...

Test

private void UpdateMatricesOptimized(ref Matrix world0, ref Matrix view0, ref Matrix projection0,ref Matrix world1, ref Matrix view1, ref Matrix projection1,ref Matrix world2, ref Matrix view2, ref Matrix projection2,ref Matrix world3, ref Matrix view3, ref Matrix projection3,ref Matrix world4, ref Matrix view4, ref Matrix projection4,ref Matrix world5, ref Matrix view5, ref Matrix projection5,

Results

Problema 2

Memoria compartida entre structs

public struct Vector

{

public float X;

public float Y;

public float Z;

public Vector(float x, float y, float z)

{

this.X = x;

this.Y = y;

this.Z = z;

}

public override string ToString()

{

return string.Format("(X:{0} Y:{1} Z:{2})", X, Y, Z);

}

}

public void XNAMethod(ref Microsoft.Xna.Framework.Vector3 vector)

Primera Idea

Vector myVector = new Vector(1,2,3);

Vector3 xnaVector = (Vector3)myVector;

Error 1 Cannot convert type 'WindowsGame1.Vector' to 'Microsoft.Xna.Framework.Vector3'

Vector myVector = new Vector(1,2,3);

Vector3 xnaVector = new Vector3() { X = myVector.X, Y = myVector.Y, Z = myVector.Z };

Segunda idea[StructLayout(LayoutKind.Explicit)]

public struct UnionVector

{

[FieldOffset(0)]

public Microsoft.Xna.Framework.Vector3 XnaVector;

[FieldOffset(0)]

public OpenTK.Vector3 OpenTkVector;

[FieldOffset(0)]

public float X;

[FieldOffset(4)]

public float Y;

[FieldOffset(8)]

public float Z;

}

UnionVector myVector = new UnionVector() { X = 1, Y = 2, Z = 3};

Vector3 xnaVector = myVector.XnaVector;

OpenTK.Vector3 oTKVector3 = myVector.OpenTkVector;

Tercera ideaVector vector = new Vector(1, 2, 3);

unsafe

{

// Creamos un puntero de nuestro tipo de struct que apunta a la dirección

de memoria de nuestro vector.

Vector* pVector = &vector;

// Creamos un puntero del tipo de struct de XNA y hacemos un casting entre

punteros.

Vector3* pVector3 = (Vector3 *)pVector;

// Los métodos de XNA no permiten pasar como parámetro un puntero, por lo

que necesitamos la última conversión.

Vector3 vector3 = *pVector3;

XNAMethod(vector3);

}

Tercera idea

Vector vector = new Vector(1, 2, 3);

unsafe

{

XNAMethod(*(Vector3*)&vector);

}

Vector vector = new Vector(1, 2, 3);

unsafe

{

XNAMethod(ref *(Vector3*)&vector);

}

Problema 3

Primera idea

Thank you

Javier Cantón Ferrero

@jcant0n

http://geeks.ms/blogs/jcanton/