Pergunta

É Interlocked.Increment(ref x) mais rápido ou mais lento do que x++ para ints e longos em várias plataformas?

Foi útil?

Solução

É mais lento, uma vez que obriga a ação para ocorrer atomicamente e atua como uma barreira de memória, eliminando a capacidade do processador à memória re-fim de acessos em todo o instrução.

Você deve estar usando Interlocked.Increment quando você quer a ação a ser atômicas em estado que pode ser compartilhado entre threads -. Não é destinado a ser um substituto completo para x ++

Outras dicas

Em nossa experiência o InterlockedIncrement () et al no Windows são impactos muito significativos. Em um caso amostra fomos capazes de eliminar o bloqueio eo uso ++ / - em vez disso. Este tempo de execução reduzida sozinho a partir de 140 segundos para 110 segundos. A minha análise é que o bloqueio força uma ida e volta de memória (caso contrário, como outros núcleos poderia vê-lo?). Um cache L1 de leitura / gravação é de cerca de 10 ciclos de relógio, mas uma memória de leitura / gravação mais como 100.

Neste caso amostra, eu estimou o número de operações de incremento / decremento em cerca de 1 bilhão. Então, em uma 2Ghz CPU isso é algo como 5 segundos para os ++ / -, e 50 segundos para o bloqueio. Espalhe a diferença em vários tópicos, e sua estreita para 30 segundos.

Pense nisso por um momento, e você vai perceber uma chamada Increment não pode ser qualquer mais rápido do que uma simples aplicação do operador de incremento. Se fosse, então a implementação do compilador do operador de incremento chamaria Increment internamente, e eles executar o mesmo.

Mas, como você pode ver, testando-a para si mesmo, eles não realizam o mesmo.

As duas opções têm finalidades diferentes. Use o operador de incremento em geral. Use Increment quando você precisar a operação para ser atômica e você está certo todos os outros usuários dessa variável também estão usando as operações interligadas. (Se eles não estão todos cooperando, então isso realmente não ajuda.)

É mais lento. No entanto, é a forma geral performance mais que eu conheço para alcançar a segurança do thread de variáveis ??escalares.

Será sempre mais lento porque tem de realizar um bloqueio de autocarros CPU vs apenas actualização de um registo. No entanto CPUs modernas alcançar um desempenho próximo registo por isso é insignificante, mesmo no processamento em tempo real.

Meu teste perfomance:

volátil: 65174400

Bloqueio: 62428600

interligados: 113248900

TimeSpan span = TimeSpan.FromSeconds(5);

object syncRoot = new object();
long test = long.MinValue;

Do(span, "volatile", () => {

    long r = Thread.VolatileRead(ref test);

    r++;

    Thread.VolatileWrite(ref test, r);
});

Do(span, "lock", () =>
{
    lock (syncRoot)
    {
        test++;
    }
});

Do(span, "interlocked", () =>
{
    Interlocked.Increment(ref test);
});
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top