Pergunta

EDIT:? Posso executar o mesmo programa duas vezes, simultaneamente, sem qualquer problema - como posso duplicar esta com OpenMP ou com algum outro método

Esta é a estrutura básica do 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();
   }
}

eu tenho verificado que, quando alguma memória é tentada a ser desalocada através MemDeallocFunctionInDLL(), a afirmação _CrtIsValidHeapPointer() falhar.

É isto porque ambos os segmentos estão escrevendo para a mesma memória?

Assim, para corrigir isso, eu pensei que eu faria SomeClass privado (isto é totalmente estranho para mim, portanto, qualquer ajuda é apreciada).

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

e agora ele falhar quando ele tenta alocar de memória no início de Data.

Nota: eu posso fazer alterações na DLL, se necessário

Nota: Corre-se perfeitamente sem #pragma omp parallel for

EDIT: aparência Agora Bar como este:

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

Ainda sem sorte.

Foi útil?

Solução

Confira MemAllocFunctionInDLL, FunctionDefinedInDLL, MemDeallocFunctionInDLL são thread-safe ou re-entrantes . Em outras palavras, fazer essas funções variáveis ??estáticos ou variáveis ??compartilhadas? Nesse caso, você precisa fazer com certeza essas variáveis ??não estão corrompidos por outros threads.

O fato sem omp-for é bom pode significar que você não escrever corretamente algumas funções para ser thread-safe.

Eu gostaria de ver que tipo de funções de alocação de memória / Free foi usado em Mem. (Alloc | Dealloc) FunctionInDLL

Adicionado : Eu tenho certeza que as suas funções na DLL não é thread-safe. Você pode executar este programa simultaneamente sem problema. Sim, ele deve estar bem menos que seu programa usa recursos compartilhados em todo o sistema (como memória global ou de memória compartilhada entre os processos), o que é muito raro. Neste caso, as variáveis ??não compartilhado em tópicos, assim que seu programa funciona bem.

Mas, invocando essas funções em mutithreads (isso significa em um único processo) falhou em seu programa. Isso significa que há algumas variáveis ??compartilhadas entre threads, e poderia ter sido corrompido.

Não é um problema de OpenMP, mas apenas um bug multithreading. Poderia ser simples de resolver este problema. Por favor, dê uma olhada as funções DLL se eles são seguros para ser chamado em simultâneo por vários threads.

Como privatizar variáveis ??estáticas

dizer que temos essas variáveis ??globais:

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

A privatização não é senão uma criação de privada copiar para cada segmento.

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

E, em seguida, quaisquer referências sobre essas variáveis ??são

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

Sim, é bastante simples. No entanto, este tipo de código pode ter um href="http://en.wikipedia.org/wiki/False_sharing" rel="nofollow noreferrer"> falso compartilhamento problema

Em primeiro lugar, apenas tentar privatizar qualquer estático e variáveis ??globais. Em seguida, verifique-correção. Em seguida, veja a aceleração você iria ficar. Se a aceleração é escalável (dizem 3,7x mais rápido em quad core), então está tudo bem. Mas, em caso de baixa aceleração (como 2x aceleração em quad core), então provavelmente você olhar para o problema de compartilhamento falsa. Para resolver o problema de compartilhamento falso, tudo que você precisa fazer é apenas colocar algum estofamento em estruturas de dados.

Outras dicas

Em vez de

delete Data

você deve escrever

delete [] Data;

Onde quer que você faz new [], certifique-se de usar delete [].

Parece que o problema não é específico para OpenMP. Você tentou executar o aplicativo sem incluir #pragma paralelo?

padrão (compartilhada) significa todas as variáveis ??são compartilhados entre threads, o que não é o que você quer. Mudança que a padrão (nenhum).

Privado (X) fará uma cópia do X para cada segmento, no entanto, nenhum deles será inicializado de modo que qualquer construção não vai necessariamente ser executada.

Eu acho que você seria melhor com a sua abordagem inicial, coloque um ponto de interrupção na chamada Dealloc, e ver o que o ponteiro de memória é eo que ele contém. Você pode ver o guarda bytes para dizer se a memória foi substituído no Final de uma única chamada, ou depois de um fio.

A propósito, estou assumindo Isso funciona se você executá-lo uma vez, sem o loop omp?

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top