Pregunta

Estoy tratando de calcular el número de transiciones que se harían en una corrida de GOL de Conway para una matriz P x Q para n iteraciones. Por ejemplo, dada 1 iteración con el estado inicial siendo 1 el intermitente (como abajo). habría 5 transiciones (2 nacimientos, 1 de supervivencia, 2 muertes por subpoblación). Ya tengo este trabajo, pero me gustaría convertir esta lógica para funcionar usando CUDA. A continuación es lo que quiero a puerto para CUDA.

text alt código:

    static void gol() // call this iterations x's
    {
        int[] tempGrid = new int[rows * cols]; // grid holds init conditions
        for (int i = 0; i < rows; i++)
        {
            for (int j = 0; j < cols; j++)
            {
                tempGrid[i * cols + j] = grid[i * cols + j];
            }
        }

        for (int i = 0; i < rows; i++)
        {
            for (int j = 0; j < cols; j++)
            {
                int numNeighbors = neighbors(i, j); // finds # of neighbors

                if (grid[i * cols + j] == 1 && numNeighbors > 3)
                {
                    tempGrid[i * cols + j] = 0;
                    overcrowding++;
                }
                else if (grid[i * cols + j] == 1 && numNeighbors < 2)
                {
                    tempGrid[i * cols + j] = 0;
                    underpopulation++;
                }
                else if (grid[i * cols + j] == 1 && numNeighbors > 1)
                {
                    tempGrid[i * cols + j] = 1;
                    survival++;
                }
                else if (grid[i * cols + j] == 0 && numNeighbors == 3)
                {
                    tempGrid[i * cols + j] = 1;
                    birth++;
                }
            }
        }

        grid = tempGrid;
    }
¿Fue útil?

Solución

Su principal desaceleración va a ser el acceso de memoria principal. Así que me gustaría sugerir que usted escoja un tamaño de bloque de hilo bastante grande basado en el hardware que tiene disponible. 256 (16x16) es una opción buena para la compatibilidad en hardware cruz. Cada una de estas secuencias de roscado se va a calcular los resultados para una sección ligeramente más pequeño de la junta - si se ha utilizado 16x16, van a calcular los resultados para una sección de 14x14 de la junta, ya que hay un borde de un elemento. (La razón para utilizar un bloque de 16x16 a 14x14 calcular un trozo más que un trozo de 16x16 es para memoria de lectura coalescencia.)

Dividir la tabla hacia arriba en (por ejemplo) 14x14 trozos; ese es su rejilla (organizado sin embargo le parezca, pero lo más probable es algo así como board_width / 14, board_height / 14.

Dentro de los núcleos, cada carga tiene su elemento de rosca en la memoria compartida. syncthreads entonces. Luego haga que los elementos medios 14x14 calcular el nuevo valor (utilizando los valores almacenados en la memoria compartida) y escribir de nuevo en la memoria global. El uso de memoria compartida ayuda a minimizar mundial lecturas y escrituras. Esta es también la razón de que su tamaño de bloque de rosca tan grande como sea posible -. Los bordes y las esquinas se "desperdicia" accesos de memoria a nivel mundial, ya que los valores descabellada no sólo se les utiliza de 1 a 3 veces, 9 veces no

Otros consejos

He aquí una manera que podría proceder:

  1. Cada hilo hace que el cálculo para 1 elemento de la cuadrícula
  2. cada hilo primeras cargas de hasta un elemento de la red principal en la memoria compartida
  3. Temas en el borde de la necesidad secuencia de rosca también para cargar los elementos de borde
  4. Cada hilo puede entonces hacer su Cálculo de la supervivencia en función del contenido de la memoria compartida
  5. Cada hilo luego escribe su resultado a la memoria principal
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top