개발관련/C#

Thread Synchronization spinlock vs lock performance

Diademata 2022. 12. 20. 23:31
반응형
//spin lock
public void Add(T item)
{
    bool locked = false;
    _spinLock.Enter(ref locked);
    _vector.Add(item);
    _spinLock.Exit();
}

//lock
public void Add(T item)
{
    lock(this.SyncRoot)
    {
        _vector.Add(item);
    }
}

사용가능한 쓰레드를 모두 사용했을때 결과 

lock을 사용한 결과 2.310, 1.876 ms

spin lock을 사용한 결과 47.241 ms, 62.261ms

 

public class Benchmark
{
    [Benchmark]
    public void ThreadSpinLock()
    {
        Kosher.Collections.SynchronizedVector2<int> synchronizedVector = new SynchronizedVector2<int>(10000);
        Parallel.For(0, 10000, (i) =>
        {
            synchronizedVector.Add(i);
        });
    }

    [Benchmark]
    public void ThreadLock()
    {
        Kosher.Collections.SynchronizedVector<int> synchronizedVector = new SynchronizedVector<int>(10000);
        Parallel.For(0, 10000, (i) =>
        {
            synchronizedVector.Add(i);
        });
    }
}

쓰레드의 경합이 많아질수록 SpinLock의 처리속도는 늦어진다.

public class Benchmark
{
        [Benchmark]
        public void ThreadSpinLock()
        {
            Kosher.Collections.SynchronizedVector2<int> synchronizedVector = new SynchronizedVector2<int>(10000);

            var option = new ParallelOptions();
            option.MaxDegreeOfParallelism = 2;
            Parallel.For(0, 10000, option, (i) =>
            {
                synchronizedVector.Add(i);
            });
        }

        [Benchmark]
        public void ThreadLock()
        {
            var option = new ParallelOptions();
            option.MaxDegreeOfParallelism = 2;
            Kosher.Collections.SynchronizedVector<int> synchronizedVector = new SynchronizedVector<int>(10000);
            Parallel.For(0, 10000, (i) =>
            {
                synchronizedVector.Add(i);
            });
        }
    }

다만 쓰레드의 경합이 없는 경우 Thread Context Switching 이 없기에 Spin Lock의 속도가 더 잘나온다.

반응형