Pergunta

estamos correndo em questões de desempenho, e um culpado potencial é um uso centralizado de um singleton voláteis. o código específico é da forma

class foo {
  static volatile instance;
  static object l = new object();

  public static foo Instance {
    if (instance == null)
      lock(l) {
        if (instance == null)
          instance = new foo();
      }

    return foo();
  }
}

este está sendo executado em uma caixa de 8-way, e estamos vendo a troca de contexto para a melodia de 500.000 por segundo. recursos típicos do sistema estão bem -. 25% util cpu, 25% de memória util, baixo IO, sem paginação, etc

faz usando um campo volátil induzir uma barreira de memória ou qualquer tipo de cpu cache de recarga? ou será que basta ir depois de memória principal de cada vez, para que o campo só?

Foi útil?

Solução

lock induz uma barreira de memória, por isso, se você está sempre acessando exemplo, em um bloqueio não é necessário o volátil.

De acordo com a este local :

Os C # voláteis implementos-chave adquirir e libertação semântica, o que implica uma barreira de memória de leitura em leitura e uma barreira de memória de gravação em gravação.

Outras dicas

Uma coisa vontade volátil não é causa de uma mudança de contexto. Se você está vendo 500.000 alternâncias de contexto por segundo, isso significa que seus tópicos estão bloqueando em alguma coisa e volátil é não o culpado.

Infelizmente, o singleton tem uma má reputação para quase tudo:)

Este não é o meu domínio de especialização, mas tanto quanto eu sei não há nada de especial sobre volátil diferente do compilador / run-time não re-ordenação ler / escreve (para a variável) para fins de otimização.

Edit: Eu estou corrigido. Não só volátil introduzir barreiras de memória, mas o que se passa (e, incidentalmente, o desempenho) depende muito da CPU particular envolvida. Consulte http://dotnetframeworkplanet.blogspot.com /2008/11/volatile-field-and-memory-barrier-look.html

É por isso que você ainda precisa de fechadura.

As perguntas que pode / não pode já ter sido respondidas:

  1. O que é a instância singleton realmente fazendo? Talvez o código de exemplo precisa ser reformulado ...
  2. O que é a contagem da linha do processo de execução? Uma caixa de 8 maneira não irá ajudá-lo se você tiver uma contagem anormalmente elevada fio.
  3. Se for maior do que o esperado, por quê?
  4. O que mais está sendo executado no sistema?
  5. O problema de desempenho consistente?

No seu exemplo aqui, volátil não deve ser objecto de qualquer "desaceleração". O bloqueio (), no entanto, pode envolver enormes roundtrips para o kernel, especialmente se houver um monte de contenção para o bloqueio.

Não há realmente nenhuma necessidade de bloquear o seu singleton neste caso, você poderia apenas fazer

class Foo {
  static Foo instance = new Foo();
  public static Foo FooInstance() {
    return instance ;
  }
}

Claro que, se 'instância' é usado em um monte de diferentes threads, você ainda tem que lock () qualquer coisa que altera que Foo, a menos que todos os métodos / propriedades de Foo é somente leitura. por exemplo.

 class Foo {
      static Foo instance = new Foo();
      object l = new object();
      int doesntChange = 42;
      int canChange = 123;
      public static Foo FooInstance() {
        return instance ;
      }
      public void Update(int newVal) {
         lock(l) { // you'll get a lot of trouble without this lock if several threads accesses the same FOO. Atleast if they later on read that variable 
            canChange = newVal;
         }

      public int GetFixedVal() {
         return doesntChange; //no need for a lock. the doesntChange is effectivly read only
      }
    }

Não há realmente nenhuma necessidade para o uso de volátil para um singleton, como você está definindo-o exatamente uma vez - e travando o código os define. Veja o artigo Jon Skeet em singletons para mais informações.

A resposta curta é, sim ele cria uma barreira de memória (flushes tudo e vai para a memória principal, e não apenas essa variável única), mas Não, não vai ser a causa da mudança de contexto.

Além disso, como já foi mencionado, eu não acredito volátil é necessário aqui.

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