Partilhar via


Redução da contenção de heap

Os gerentes de seqüência de caracteres padrão fornecidos pelo MFC e ATL são invólucros simples na parte superior de um global heap.Isso global heap é totalmente thread-safe, que significa que vários threads podem alocar e liberar memória dele simultaneamente sem corromper o heap.Para ajudar a fornecer a acesso thread-safe, o heap tem para serializar o acesso a mesmo.Geralmente isso é feito com um mecanismo de bloqueio semelhante ou uma seção crítica.Sempre que dois threads tentarem acessar o heap simultaneamente, um thread é bloqueado até que de solicitação do Outros thread seja concluída.Para muitos aplicativos, essa situação raramente ocorre e o impacto no desempenho do mecanismo de bloqueio da heap é insignificante.No entanto, para aplicativos com que freqüência acesso a pilha de vários threads contenção de bloquear da heap pode fazer com que o aplicativo seja executado mais lentamente do que se fosse um único encadeamento (mesmo em máquinas com várias CPUs).

Aplicativos que usam CStringT são especialmente suscetíveis a contenção de heap porque as operações em CStringT objetos freqüentemente requerem realocação do buffer de seqüência de caracteres.

Uma maneira de aliviar a contenção de heap entre threads é que cada thread alocar seqüências de caracteres de um heap particular e o local de segmento.Desde que sistema autônomo seqüências de caracteres alocado com alocador de um segmento específico são usados apenas nesse segmento, o alocador não precisa ser thread-safe.

Exemplo

O exemplo abaixo ilustra um procedimento de thread aloca seu próprio heap thread safe particular a ser usado para as seqüências de caracteres desse segmento:

DWORD WINAPI WorkerThreadProc(void* pBase)
{
   // Declare a non-thread-safe heap just for this thread:
   CWin32Heap stringHeap(HEAP_NO_SERIALIZE, 0, 0);

   // Declare a string manager that uses the thread's heap:
   CAtlStringMgr stringMgr(&stringHeap);

   int nBase = *((int*)pBase);
   int n = 1;
   for(int nPower = 0; nPower < 10; nPower++)
   {
      // Use the thread's string manager, instead of the default:
      CString strPower(&stringMgr);

      strPower.Format(_T("%d"), n);
      _tprintf_s(_T("%s\n"), strPower);
      n *= nBase;
   }

   return(0);
}

Comentários

Vários segmentos podem estar em execução usando este procedimento thread mesmo, mas uma vez que cada segmento possui sua própria heap não há nenhuma contenção entre segmentos.Além disso, o fato de que cada heap é thread-safe proporciona um aumento mensurável no desempenho, mesmo se apenas uma cópia do segmento está em execução.Esse é o resultado da pilha não usando operações interligadas caras para proteger contra o acesso simultâneo.

Para obter um procedimento de thread mais complicado, talvez seja conveniente armazenam um ponteiro para o gerente de seqüência de caracteres do segmento em um slot de armazenamento local (TLS) do segmento.Isso permite que outras funções chamadas pelo procedimento para acessar o Gerenciador de seqüência de caracteres do segmento do thread.

Consulte também

Conceitos

Gerenciamento de memória com CStringT