2010-06-30 20 views
9

Hola: ¿El tamaño global de trabajo (dimensiones) tiene por qué ser múltiplo del tamaño de grupo de trabajo (Dimensiones) en OpenCL?¿El tamaño de trabajo global debe ser múltiplo del tamaño del grupo de trabajo en OpenCL?

En caso afirmativo, ¿existe una forma estándar de manejar las matrices no un múltiplo de las dimensiones del grupo de trabajo? Puedo pensar en dos posibilidades:

Establezca dinámicamente el tamaño de las dimensiones del grupo de trabajo a un factor de las dimensiones de trabajo globales. (Esto implicaría la sobrecarga de encontrar un factor y posiblemente establecer el grupo de trabajo en un tamaño no óptimo.)

Aumente las dimensiones del trabajo global para que sea el múltiplo más cercano de las dimensiones del grupo de trabajo, manteniendo todas las entradas y los buffers de salida son los mismos, pero verifica los límites en el kernel para evitar segfaulting, es decir, no hacer nada en los elementos de trabajo fuera de límite de la salida deseada. (Esta parece ser la mejor manera).

¿Funcionaría la segunda manera? ¿Hay una mejor manera? (¿O no es necesario porque las dimensiones del grupo de trabajo no necesitan dividir las dimensiones de trabajo globales?)

¡Gracias!

+0

Es interesante que usted haga esta pregunta, ya que yo mismo la estaba preguntando. Mi primera suposición es que mantienes un tamaño de grupo de trabajo fijo y manejas fuera de límite por una rama if. – Stringer

Respuesta

7

Thx para el enlace Chad. Pero en realidad, si usted lee en:

Si se especifica local_work_size, los valores especificados en global_work_size [0], ... global_work_size [work_dim - 1] debe ser uniformemente divisible por los valores correspondientes se especifican en local_work_size [0 ], ... local_work_size [work_dim - 1].

Por lo tanto, SÍ, el tamaño de trabajo local debe ser un múltiplo del tamaño de trabajo global.

También creo que la asignación del tamaño de trabajo global al múltiplo más cercano y tener cuidado con los límites debería funcionar, publicaré un comentario cuando lo intente.

1

De acuerdo con el estándar que no tiene que ser por lo que vi. Creo que lo manejaría con una sucursal, pero no sé exactamente qué tipo de operación matricial estás haciendo.

http://www.khronos.org/registry/cl/specs/opencl-1.1.pdf#page=131

global_work_size puntos en una matriz de work_dim valores sin signo que describir el número de elementos de trabajo globales en work_dim dimensiones que ejecutará la función del núcleo. El número total de elementos de trabajo globales es calculado como global_work_size[0] * ... * global_work_size[work_dim – 1].

los valores especificados en global_work_size + valores especificados en global_work_offset no puede exceder la gama propuesta por el sizeof(size_t) para el dispositivo en que la ejecución kernel será en cola correspondiente. El sizeof(size_t) para un dispositivo se puede determinar usando CL_DEVICE_ADDRESS_BITS en la Tabla 4.3. Si, por ejemplo, CL_DEVICE_ADDRESS_BITS = 32, es decir, el dispositivo utiliza una dirección espacio de 32 bits, size_t es un 32 bits sin signo número entero y global_work_size valores debe estar en el rango de 1 .. 2^32 - 1 . valores fuera de este rango devuelven un error CL_OUT_OF_RESOURCES.

1

Parece ser una publicación anterior, pero permítanme actualizar esta publicación con información nueva. Con suerte, podría ayudar a alguien más.

el tamaño sí Trabajo Global (Dimensiones) tienen que ser múltiplo de Grupo de Trabajo tamaño (dimensiones) en OpenCL?

Respuesta: True till OpenCL 2.0. Antes de CL2.0, su tamaño de trabajo global debe ser un múltiplo del tamaño de trabajo local; de lo contrario, recibirá un mensaje de error cuando ejecute clEnqueueNDRangeKernel.

Pero desde CL2.0, ya no es necesario. Puede usar cualquier tamaño de trabajo global que se ajuste a las dimensiones de su aplicación. Sin embargo, recuerde que la implementación de hardware podría seguir utilizando la forma "antigua", lo que significa rellenar el tamaño del grupo de trabajo global. Por lo tanto, hace que el rendimiento dependa en gran medida de la arquitectura del hardware. Puede ver un rendimiento bastante diferente en diferentes hardware/plataformas. Además, desea que su aplicación vuelva a ser compatible para admitir una plataforma más antigua que solo admita CL hasta la versión 1.2. Por lo tanto, creo que esta nueva característica añadida en CL2.0 es sólo para una fácil programación, para obtener un mejor rendimiento controlable y compatibilidad con versiones anteriores, le sugiero que todavía utiliza el siguiente método mencionado por usted:

aumentar las dimensiones de la trabajo global para ser el múltiplo más cercano de las dimensiones del grupo de trabajo, manteniendo todos los búferes de entrada y salida el mismo pero verificando los límites en el kernel para evitar segfaulting, es decir, hacer nada en los elementos de trabajo sin límite del resultado deseado. (Esto parece la mejor manera).

Respuesta: tiene toda la razón. Esta es la forma correcta de manejar este caso. Diseñe con cuidado el tamaño del grupo de trabajo local (teniendo en cuenta factores como el uso del registro, el acierto/fallo de la memoria caché, el patrón de acceso a la memoria, etc.). Y luego agregue su tamaño de trabajo global a un múltiplo del tamaño de trabajo local. Entonces, ya puedes irte.

Otra cosa a tener en cuenta es que puede utilizar el objeto de imagen para almacenar los datos en lugar del búfer, si hay bastante trabajo de comprobación de límites en su kernel. Para la imagen, la verificación de límites se realiza automáticamente por hardware, casi sin gastos generales en la mayoría de las implementaciones. Por lo tanto, rellenando su tamaño de trabajo global, almacene sus datos en un objeto de imagen, luego, solo necesita escribir su código normalmente sin preocuparse por la verificación de límites.

Cuestiones relacionadas