59 votos

¿Por qué es el! = operador no permitido con OpenMP.

Yo estaba tratando de elaborado el siguiente código:

#pragma omp parallel shared (j)
{
   #pragma omp for schedule(dynamic)
   for(i = 0; i != j; i++)
   {
    // do something
   }
}

Me sale este error: error: invalid control de predicado.

Puedo comprobar la openMP guía de referencia y se dice que por el paralelo "sólo" permite a uno de los siguientes operadores: < <= > >=.

No entiendo por qué no permitir i != j. Yo podría entender si era la estática de programación, ya que openMP es necesario pre-calcular el número de iteraciones que se asigna a cada hilo. Pero no puedo entender el porqué de esta limitación, en tal caso, por ejemplo. Alguna pista ?


EDIT: incluso si hago for(i = 0; i != 100; i++), aunque podría simplemente poner"<""<=".

46voto

dreamcrash Puntos 8227

.

Enviar un correo electrónico a la OpenMP los desarrolladores acerca de este tema, la respuesta :

Para signed int, el ceñido alrededor de comportamiento no está definido. Si permitimos !=, los programadores pueden obtener inesperado tripcount. El problema es si el compilador puede generar código para calcular un conteo de viajes para el bucle.

Para un circuito simple, como:

for( i = 0; i < n; ++i )

el compilador puede determinar que hay 'n' iteraciones, si n>=0, y cero iteraciones si n < 0.

Para un bucle como:

for( i = 0; i != n; ++i ) 

de nuevo, un compilador debe ser capaz de determinar que hay 'n' iteraciones, si n >= 0; si n < 0, no sabemos cuántas iteraciones se tiene.

Para un bucle como:

for( i = 0; i < n; i += 2 )

el compilador puede generar código para calcular el conteo de viajes (bucle de iteraciones) como piso((n+1)/2), si n >= 0, y 0 si n < 0.

Para un bucle como:

for( i = 0; i != n; i += 2 )

el compilador no puede determinar si el 'yo' se haya golpeado a 'n'. Lo que si " n " es un número impar?

Para un bucle como:

for( i = 0; i < n; i += k )

el compilador puede generar código para calcular el conteo de viajes como piso((n+k-1)/k) si n >= 0, y 0 si n < 0, porque el compilador sabe que el bucle debe contar; en este caso, si k < 0, no es legal OpenMP programa.

Para un bucle como:

for( i = 0; i != n; i += k )

el compilador no sabe si me está contando hacia arriba o hacia abajo. No sé si 'yo' nunca hit 'n'. Puede ser un bucle infinito.

Credites: OpenMP ARB

16voto

Hristo Iliev Puntos 29262

Contrario a lo que pueda parecer, schedule(dynamic) no funciona con la dinámica del número de elementos. En lugar de la asignación de iteración de bloques de hilos es lo que es dinámico. Con la estática de la programación de esta asignación se calcula previamente al comienzo de la worksharing construir. Con la programación dinámica iteración bloques se entregan a los hilos en el primer llegado, primer servido base.

El estándar OpenMP es bastante claro que la cantidad de iteratons es precalculadas una vez que el deltaview construir se encuentra, por lo tanto el contador del bucle no puede ser modificado dentro del cuerpo del bucle (OpenMP 3.1 especificación, §2.5.1 - Construcción de Bucle):

El número de iteraciones para cada bucle se calcula antes de la entrada a la ultraperiféricas bucle. Si la ejecución de cualquier bucle asociado cambios en cualquiera de los valores utilizados para calcular cualquier de la iteración cuenta, entonces el comportamiento no está especificado.

El tipo entero (o en especie, para Fortran) se utiliza para calcular el número de iteraciones para la se derrumbó bucle es definido por la implementación.

Un worksharing bucle lógico iteraciones numeradas 0,1,...,N-1, donde N es el número de bucle de iteraciones, y la lógica de numeración indica la secuencia en la que las iteraciones se ejecutará si el bucle asociado(s) fueron ejecutados por un solo hilo. El schedule cláusula especifica cómo las iteraciones de los asociados de bucles se dividen en contiguo no vacía de subconjuntos, llamado trozos, y cómo estos trozos se distribuyen entre los hilos del equipo. Cada subproceso se ejecuta su bloque(s) en el contexto de su tarea implícita. El chunk_size expresión se evalúa mediante los originales de los artículos de la lista de las variables que son hechas de forma privada en la construcción de bucle. Es indefinido si, en qué orden, o cuántas veces, efectos secundarios de la evaluación de esta expresión se producen. El uso de una variable en un schedule cláusula de expresión de una construcción de bucle hace una referencia implícita a la variable en todos los encierra las construcciones.

El razonamiento detrás de estas operador relacional restricción es muy simple - se proporciona una indicación clara sobre lo que es la dirección del bucle, que permite el fácil cálculo del número de iteraciones, y similares de la semántica de la OpenMP worksharing directiva en C/C++ y Fortran. También otras operaciones relacionales requeriría un examen minucioso del cuerpo del bucle en el fin de entender cómo el lazo va que sería unaceptable en muchos casos, y podría hacer que la implementación engorroso.

OpenMP 3.0 introdujo la explícito task constructo que permite parallelisation de los nudos con que se desconoce el número de iteraciones. Sin embargo hay una captura: tareas de introducir algunos severa sobrecarga y una tarea por cada iteración del bucle sólo tiene sentido si estas iteraciones tomar bastante tiempo para ser ejecutado. De lo contrario, la sobrecarga que habría de dominar el tiempo de ejecución.

7voto

Jonathan Dursi Puntos 25143

Hay un millón funcionalmente equivalente cosas que podrían en principio ser permitidos:

for (int i=0; (i-j)!=0; i++) 
    ....

o

for (int i=0, k=j; (i!=j)&&(k!=0); i++, k--)

o

for (int i=0; i-j < 1 && j-i < 1; i++)
    ....

o

inline int f(int i, int j) {
    return (i != j);
}

..

for (int i=0; f(i,j); i++) 
        ....

Pero en última instancia, el compilador de los escritores han de implementar las directivas de OpenMP que debe apoyar, entre otras cosas, eficiente estática de la descomposición del bucle entre los procesadores, con una cantidad finita de recursos. El estándar es el documento que intenta dibujar un equilibrio entre la flexibilidad y la facilidad de uso para los desarrolladores, por un lado, y de trazabilidad por parte de los ejecutores.

Ciertamente se podría intentar dar respuesta a la comisión; no me puedo imaginar este caso en particular sería especialmente difícil para los ejecutores. Por otro lado, no veo que el particular notación para un bucle de todos los que a menudo, así que no sé cómo de alta prioridad sería; no es como pedir a los desarrolladores a cambio de un != a < o > es una enorme imposición.

4voto

bobcgausa Puntos 41

La respuesta es simple. OpenMP no permite la terminación prematura de un equipo de hilos. Con == o! =, OpenMP no tiene manera de determinar cuando el bucle se detiene. 1. uno o más hilos podrían golpear la condición de terminación, que puede no ser única. 2. OpenMP no tiene manera de cerrar los otros subprocesos que nunca podrían detectar la condición.

2voto

Richard Puntos 5991

Si yo fuera a ver la declaración de

for(i = 0; i != j; i++)

se utiliza en lugar de la declaración

for(i = 0; i < j; i++)

Yo sería preguntarse por qué el programador había hecho esa elección, no importa que se puede decir la misma cosa. Puede ser que OpenMP es una sintáctico de la elección con el fin de forzar una cierta claridad de código.

Aquí el código de lo que plantea desafíos para el uso de != y puede ayudar a explicar por qué no es permitido.

#include <cstdio>

int main(){
    int j=10;
   #pragma omp parallel for
   for(int i = 0; i < j; i++){
    printf("%d\n",i++);
   }
}

aviso que i se incrementa en tanto el for instrucción así como en el bucle de sí mismo que lleva a la posibilidad (pero no la garantía) de un bucle infinito.

Si el predicado es < entonces el bucle del comportamiento puede estar aún bien definido en paralelo en un contexto sin el compilador de tener que comprobar en el bucle para que los cambios i y la determinación de cómo los cambios afectarán a la del bucle límites.

Si el predicado es != entonces el bucle del comportamiento no está bien definida y puede ser infinito en extensión, la prevención de fácil paralelo de la subdivisión.

Iteramos.com

Iteramos es una comunidad de desarrolladores que busca expandir el conocimiento de la programación mas allá del inglés.
Tenemos una gran cantidad de contenido, y también puedes hacer tus propias preguntas o resolver las de los demás.

Powered by:

X