Pregunta

EDIT:? que se puede ejecutar el mismo programa dos veces, al mismo tiempo sin ningún problema - cómo puedo duplicar este con OpenMP o con algún otro método

Este es el marco básico del problema.

//Defined elsewhere
class SomeClass
{
public:
  void Function()
  {
    // Allocate some memory
    float *Data;
    Data = new float[1024];

    // Declare a struct which will be used by functions defined in the DLL
    SomeStruct Obj;
    Obj = MemAllocFunctionInDLL(Obj);

    // Call it
    FunctionDefinedInDLL(Data,Obj);

    // Clean up
    MemDeallocFunctionInDLL(Obj);
    delete [] Data;        
  }
}

void Bar()
{
   #pragma omp parallel for
   for(int j = 0;j<10;++j)
   {
     SomeClass X;
     X.Function();
   }
}

He verificado que cuando un recuerdo se trató de cancelar la asignación a través MemDeallocFunctionInDLL(), la afirmación _CrtIsValidHeapPointer() falla.

Es esto porque ambos hilos están escribiendo a la misma memoria?

Así que para solucionar este problema, pensé que me gustaría hacer SomeClass privada (esto es totalmente ajeno a mí, por lo que cualquier ayuda se agradece).

void Bar()
{
   SomeClass X;
   #pragma omp parallel for default(shared) private(X)
   for(int j = 0;j<10;++j)
   {         
     X.Function();
   }
}

y ahora se produce un error cuando se trata de asignar de memoria en el principio de Data.

Nota: que puedo realizar cambios en el archivo DLL, si es necesario

Nota: Se ejecuta perfectamente sin #pragma omp parallel for

EDIT: Ahora Bar se ve así:

void Bar()
{
   int j
   #pragma omp parallel for default(none) private(j)
   for(j = 0;j<10;++j)
   {
     SomeClass X;         
     X.Function();
   }
}

Todavía no hay suerte.

¿Fue útil?

Solución

Salida MemAllocFunctionInDLL, FunctionDefinedInDLL, MemDeallocFunctionInDLL son seguro para subprocesos o reentrante . En otras palabras, hacer estas funciones variables estáticas o variables compartidas? En tal caso, es necesario para que sea seguro de estas variables no están corrompidos por otros hilos.

El hecho sin OMP-a está bien podría significar que no escribió correctamente algunas funciones a ser flujos seguros.

Me gustaría ver qué tipo de memoria de asignación de funciones / libre ha sido utilizado en Mem (Alloc | dealloc). FunctionInDLL

añadido : Estoy bastante seguro de sus funciones en DLL no es seguro para subprocesos. Puede ejecutar este programa al mismo tiempo sin ningún problema. Sí, debería estar bien a menos que su programa utiliza recursos compartidos de todo el sistema (como la memoria global o la memoria compartida entre procesos), que es muy raro. En este caso, hay variables compartidas en las discusiones, por lo que su programa funciona bien.

Sin embargo, la invocación de estas funciones en mutithreads (que significa en un solo proceso) se bloquea su programa. Significa que hay algunas variables compartidas entre los hilos, y podría haber sido corrompidos.

No es un problema de OpenMP, pero sólo un error multihilo. Podría ser simple de resolver este problema. Por favor miren las funciones DLL si son seguros para ser llamado en concurrente por parte de muchos hilos.

¿Cómo la privatización de las variables estáticas

decir que tenemos este tipo de variables globales:

static int  g_data;
static int* g_vector = new int[100];

La privatización no es más que una creación privado copia para cada hilo.

int  g_data[num_threads];
int* g_vector[num_threads];
for (int i = 0; i < num_threads; ++i)
  g_vector[i] = new int[100];

Y, a continuación, todas las referencias a tales variables son

// Thread: tid
g_data[tid] = ...
.. = g_vector[tid][..]

Sí, es bastante simple. Sin embargo, este tipo de código puede tener una falso problema compartir . Sin embargo, la falsa compartición es una cuestión de rendimiento, no la corrección.

En primer lugar, sólo tratar de privatizar las variables estáticas y globales. A continuación, comprobar que la corrección. A continuación, ver el aumento de velocidad que se obtiene. Si la aceleración es escalable (digamos 3,7x más rápido en cuatro núcleos), entonces está bien. Pero, en caso de baja aceleración (como el aumento de velocidad 2x de cuatro núcleos), entonces es probable que mirar el problema de la falsa compartición. Para resolver el problema de la falsa compartición, todo lo que tiene que hacer es poner un poco de relleno en las estructuras de datos.

Otros consejos

En lugar de

delete Data

debe escribir

delete [] Data;

Siempre que sea usted nuevo [], asegúrese de usar delete [].

Parece que su problema no es específico de OpenMP. ¿Trató de ejecutar su aplicación sin incluir #pragma paralelo?

por defecto (compartido) significa que todas las variables son compartidos entre los hilos, que no es lo que desea. Cambiar eso a por defecto (ninguno).

privada (X) hará una copia de X para cada hilo, sin embargo, será inicializado ninguno de ellos por lo que no necesariamente se lleva a cabo cualquier tipo de construcción.

Creo que estaría mejor con su planteamiento inicial, poner un punto de interrupción en la llamada dealloc, y ver lo que el puntero de memoria es y lo que contiene. Se puede ver los href="http://en.wikipedia.org/wiki/Magic_number_%28programming%29" de saber si la memoria ha sido sobrescrito en el final de una sola llamada, o después de un hilo.

Por cierto, estoy asumiendo que esto funciona si se ejecuta una vez, sin el bucle de OMP?

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top