Autor Tema: Juego de la vida en CUDA (duda matemática)

0 Usuarios y 1 Visitante están viendo este tema.

13 Marzo, 2012, 04:48 pm
Leído 1979 veces

Kyra W

  • $$\Large \color{#6a84c0}\pi$$
  • Mensajes: 2
  • Karma: +0/-0
  • Sexo: Masculino
Hola a todos.

Soy estudiante del grado de informática de la uah, y es la primera vez que entro en este foro. La cuestión es que me han mandado hacer una práctica usando tarjetas gráficas (NVidia, para concretar) que, en principio, debería ser bastante sencilla: El juego de la vida, mundialmente conocido y posiblemente algo trillado para los más entendidos en el tema. Antes de nada, aclarar que mi duda es principalmente matemática, razón por la que recurro a este foro, por lo que si alguno no tiene mucha idea de programación no debe preocuparse: Al final explico claramente donde reside el problema.

La idea del juego, para los que no sepan de que va, es tener una malla de "células" (representada por una matriz bidimensional) que pueden tener dos estados: Viva (1) o Muerta (0). Cada célula Muerta puede "volver a la vida" si hay exactamente tres células vivas entre las ocho posiciones adyacentes (contando también las diagonales). Cada célula Viva muere en caso de tener más de tres células vivas alrededor (sobrepoblación) o menos de dos (soledad).

El problema radica en que, como los entendidos en CUDA y programación paralela sabrán, meter condicionales dentro de un hilo en programación paralela es uno de los crímenes que debemos evitar a toda consta, por lo que un problema que normalmente sería propio de un curso básico de programación se convierte en un verdadero quebradero de cabeza. ¿Cómo implementar el algoritmo para decidir si una célula vive o muere, sin recurrir a estructuras "if..then"?

Y paso a formalizar el problema a nivel más matemático y menos computacional:

  • Tenemos dos variables: X e Y.
  • X puede tomar valores entre 0 y 1.
  • Y puede tomar valores entre 0 y 8.

Buscamos una función f(x,y) tal que:

  • f(x,y) no puede ser una función por partes (es decir, debe poder expresarse en una línea, y sin posibilidad de incluir "condiciones" tales como "si x es tal, entonces la función devuelve tal...")
  • f(0,3) devuelve 1.
  • f(0,y), siendo y distinto de 3, devuelve 0.
  • f(1,2) y f(1,3) devuelve 1.
  • f(1,y), siendo y distinto de 2 y 3, devuelve 0

¿Hay algo parecido, o estoy pidiendo lo imposible?

Mil gracias a todos los que respondan, resuelvan o no mi problema. Aunque la pregunta es estrictamente matemática, si alguno sabe otra manera de realizar el programa sin recurrir a estos pequeños desvaríos matemáticos también me sirve su respuesta

13 Marzo, 2012, 06:24 pm
Respuesta #1

Luis Fuentes

  • el_manco
  • Administrador
  • Mensajes: 58,907
  • País: es
  • Karma: +0/-0
Hola

 Hay algo que no me convence en todo esto. Conozco la programación usual, pero no la filosofía de programación en paralelo.

 Entonces si que puede darse una función que cumpla lo que pides: de la forma más bruta tomando una interpolación polinómica o trigonométrica y pensando un poco quizá algo más fina. Pero no me parece muy lógico, muy coherente. Para un ordenador es mucho más barato evaluar una función lógica que un polinomio, o una trigonométrica. Con evaluar una función lógica no me refiero a un "if..then" si no a funciones tipo OR, AND, XOR... que devuelven valores cero o uno. De hecho entiendo son las funciones más naturales para un ordenador, y operaciones más compicadas se termiman reduciendo en el procesador a operaciones de ese tipo.

 Sin pretender  animarte a que "fusiles" el trabajo de otro, te puede ayudar este enlace:

http://www.davioth.com/?p=42

Saludos.

13 Marzo, 2012, 08:19 pm
Respuesta #2

Kyra W

  • $$\Large \color{#6a84c0}\pi$$
  • Mensajes: 2
  • Karma: +0/-0
  • Sexo: Masculino
La programación paralela es algo extraña en lo que a bucles e "ifs" se refiere. De hecho, te aconsejan que si tienes un bucle for con valores conocidos lo despliegues en el código escribiendo la operación de forma literal para cada uno de los valores (algo que se consideraría una guarrada criminal en cualquier otro tipo de paradigma de programación)

En cuanto a lo que dices de los operadores lógicos, me parece una propuesta muy interesante, y se me ha encendido la bombillita cuando lo he leído. Eso sí, veo un gran problema: No tengo claro si se puede castear una función lógica en un entero sin recurrir a un "if". Lo que se me ha ocurrido es algo así como

int resultado = (x == 0 && y == 3) || (x == 0 && (y == 2 || y == 3))

Pero yo creo que esto peta seguro. Quizás con un casteo en plan...

int resultado = (int) (x == 0 && y == 3) || (x == 0 && (y == 2 || y == 3))

Pero me parece tan guarro que... Bueno, todo sea probar XD