Una vez mirado un poco de Cg y viendo por donde van los tiros, decidi ir probando cosas de la red.
La idea es que un ordenador pueda mandar trabajos en red a varios, para realizar un trabajo en paralelo que procesara la grafica.
Lo primero es poder comunicar dos ordenadores, para eso usaremos SDL_Net y el protocolo TCP. Mas adelante se puede mirar si con UDP la mejora de velocidad compensa el trabajo extra (comprobar perdidas, desorden, etc...).
Tras iniciar SDL, las funciones que usaremos para esto son las siguientes:
- SDLNet_ResolveHost(&ip,host,port) := dado un host (ip o nombre de maquina) y un puerto, nos rellena la variable ip de tipo IPaddress. Usaremos ip para abrir los sockets. Si host es igual a NULL, se entiende que es un socket de servidor y es la maquina local.
- SDLNet_TCP_GetPeerAddress(socket) := dado un socket, devuelve una variable de tipo IPaddress con la informacion del socket.
- SDLNet_TCP_Open(&ip) := nos devuelve un socket "enganchado" a esa ip.
- SDLNet_TCP_Accept(socket) := pone el socket de servidor en modo escucha y devuelve el socket que se intenta conectar a el.
- SDLNet_TCP_Send(socket,message,len) := envia por sock, una cantidad igual de caracteres a len, del buffer message.
- SDLNet_TCP_Recv(socket,message,len) := lee de socket tantos caracteres como len (si los hay) y los guarda en el buffer message.
- SDLNet_TCP_Close(sock) := cierra un socket abierto.
Las dos primeras funciones se usan para crear un socket dada una ip y puerto, o para recibir esta informacion de un socket creado. Una vez tengamos un socket valido, la forma de usarlo es similar a la de un archivo.
Con esto ya podemos mandar un archivo de una maquina a otra. Ahora necesitamos decirle a la maquina remota que lo ejecute.
Buscando por MSDN tenemos la fortuna de encontrar la funcion CreateProcess, que crea un proceso hijo que va a ejecutar lo que le digamos, mientras nosotros con WaitForSingleObjet esperamos a que termine. Lo bueno de esta funcion esque nos ahorramos tener que crear un hijo, mandarle ejecutar y todo lo demas.
El aspecto de la funcion es el siguiente:
- CreateProcess(NULL, // No module name (use command line)
cmd, // Command line
NULL, // Process handle not inheritable
NULL, // Thread handle not inheritable
FALSE, // Set handle inheritance to FALSE
0, // No creation flags
NULL, // Use parent's environment block
NULL, // Use parent's starting directory
&si, // Pointer to STARTUPINFO structure
&pi ) // Pointer to PROCESS_INFORMATION structure
De todos los argumentos solo nos interesan los dos primeros y los dos ultimos, en realidad el unico que manejaremos "conscientemente" es el segundo. Aqui un ejemplo.
El primer argumento es el nombre del comando, si ponemos NULL lo cogera del segundo argumento, que es una cadena de palabras separadas por espacio, la primera es el comando y las siguentes sus argumentos (hay un limite de, creo, 32kb pero no nos afecta demasiado).
Los dos ultimo argumentos son punteros a estructuras de datos que utiliza windows para los procesos, las usaremos para esperar la ejecucion, y terminar.
El segundo argumento que es una lista de cadenas, puede ser algo tan sencillo como:
- "echo hola" : ejecutara el comando echo con el argumento hola, lo que hara que imprima por pantalla "hola".
- "miprograma.exe arg1 arg2 arg3" : ejecutara miprograma.exe (el .exe puede omitirse) que tiene que estar en el directorio de trabajo o en el path (lo del path no lo he comprobado), y recibe 3 argumentos.
o un poco mas complicados (por lo largo) como el que necesitamos para compilar un cpp con codigo cg:
- "cl /c /I \"C:\\Archivos de programa\\Microsoft Visual Studio .NET 2003\\Vc7\\PlatformSDK\\include\" /I \"C:\\Archivos de programa\\Microsoft Visual Studio .NET 2003\\Vc7\\include\" /I \"C:\\Archivos de programa\\NVIDIA Corporation\\Cg\\include\" main.cpp"
Las \\, \" son comandos de escape de c para que imprima \ y " respectivamente. Este comando ejecuta cl que es el compilador que viene con los visual studio, recibe varios argumentos, basicamente, ruta a includes. El ultimo argumento main.cpp es el nombre del archivo que queremos compilar, previsiblemente el que le acabamos de pasar por red. Esto nos creara un programa objeto .obj con el mismo nombre.
Despues de compilar, tendremos que linkar, esto lo hace una linea similar a la anterior:
- "link /OUT:\"main.exe\" /LIBPATH:\"C:\\Archivos de programa\\Microsoft Visual Studio .NET 2003\\Vc7\\PlatformSDK\\Lib\" /LIBPATH:\"C:\\Archivos de programa\\Microsoft Visual Studio .NET 2003\\Vc7\\Lib\" /LIBPATH:\"C:\\Archivos de programa\\NVIDIA Corporation\\Cg\\lib\" cg.lib cgGL.lib glew32.lib glu32.lib main.obj"
Y por ultimo, ejecutar nuestro programa, cuya linea sera similar al ejemplo de "miprograma.exe", el nombre que tendra el exe se lo decimos al linkador con la orden /OUT:.
Degryll....
lunes, 24 de marzo de 2008
Suscribirse a:
Entradas (Atom)