스레드로부터 안전한 고성능 랜덤 생성기

비트 코더

스레드로부터 안전한 고성능 난수 생성기가 필요합니다. 범위 내가 ulong아닌 값 유형 ( 현재는) 에서 임의의 바이트 만 필요 합니다. C # 기본 제공 Random클래스를 사용했지만 다소 느리고 스레드로부터 안전하지 않았습니다.

나중에 실제로 매우 잘 작동하는 XORShift 함수로 옮겼지만 스레드 안전성을 얻으려면 계산을에 넣어야 lock하므로 성능이 크게 저하됩니다.

무작위를 생성하는 데 사용하는 ulong것은 다음과 같습니다.

public class Rand
{
    ulong seed = 0;
    object lockObj = new object();

    public Rand()
    {
        unchecked
        {
            seed = (ulong)DateTime.Now.Ticks;
        }
    }

    public Rand(ulong seed)
    {
        this.seed = seed;
    }

    public ulong GetULong()
    {
        unchecked
        {
            lock (lockObj)
            {
                ulong t = 0;

                t = seed;
                t ^= t >> 12;
                t ^= t << 25;
                t ^= t >> 27;
                seed = t;

                return t * 0x2545F4914F6CDD1D;
            }
        }
    }
}

이것은 훌륭하고 빠르게 작동하지만 잠금은 1-2us200 개의 동시 스레드에서 호출되는 경우 시간이 걸리며 그렇지 않으면 계산이 100ns.

잠금을 제거하면 두 개의 스레드가 동일한 시드를 사용하고 내 목적에 좋지 않은 동일한 무작위를 계산할 가능성이 있습니다. 나는 제거하고있어 경우 ulong t종자에 직접 선언과 작업을 두 개의 동시 통화에 대해 동일한 랜덤를 생성하는 아주 작은 기회가있을 것입니다, 값이 값 범위에서 밖으로 이동 될 가능성이처럼, 또한이 t << 25의지 회전을 전달하지 않고 다른 스레드에 의해 연속으로 여러 번 호출되면 단순히 0이됩니다.

동시 호출에 의해 변경 될 수있는 공유 값이 있고 계산 방법에서 해당 값으로 작업하는 경우 적절한 방법이 될 것이라고 생각합니다. 이러한 값은 원자 적 (적어도 CPU 코어 포함)이기 때문에 많은 경우 문제가되지 않습니다. 계산에서 동시에 사용하지만이 값이 비트 범위에서 벗어나면 문제가됩니다.

이 문제를 해결할 좋은 해결책이 있습니까? 도움을 주시면 감사하겠습니다.

편집 : 좋아, 비동기 작업 이이 함수를 호출하기 때문에 스레드가 스레드 풀에서 무작위로 나오기 때문에 스레드 ID를 사용하는 것도 해결책이 아닙니다. 특정 스레드는이 메서드를 다시 호출하지 않으며 해당 ID에 대한 인스턴스를 유지하는 것은 좋지 않습니다.

이안 머서

잠금없이 수행 할 수 있으며 여전히 스레드로부터 안전합니다. 계산이 매우 빠르며 (그것이 그렇습니다) 주변에서 실행되는 코드가 더 느리다고 가정하면, 계산을 시작하고 완료하는 사이에 다른 스레드가이를 변경하면 단순히 재 계산하는 것이 더 빠를 것입니다. Interlocked.CompareExchange스핀 루프로 할 수 있습니다 . 유일한 어려움은 ulong 버전이 없으므로 안전하지 않은 메서드를 사용하여 동등한 것을 가져와야한다는 것입니다.

private static unsafe ulong InterlockedCompareExchange(ref ulong location,
     ulong value, ulong comparand)
{
    fixed (ulong* ptr = &location)
    {
         return (ulong)Interlocked.CompareExchange(ref *(long*)ptr, (long)value, (long)comparand);
    }
 }

public ulong GetULong()
{
    unchecked
    {
       ulong prev = seed;

       ulong t = prev;
       t ^= t >> 12;
       t ^= t << 25;
       t ^= t >> 27;

       while (InterlockedCompareExchange(ref seed, t, prev) != prev)
       {
            prev = seed;
            t = prev;
            t ^= t >> 12;
            t ^= t << 25;
            t ^= t >> 27;
       }

       return t * 0x2545F4914F6CDD1D;
    }
}

이 기사는 인터넷에서 수집됩니다. 재 인쇄 할 때 출처를 알려주십시오.

침해가 발생한 경우 연락 주시기 바랍니다[email protected] 삭제

에서 수정
0

몇 마디 만하겠습니다

0리뷰
로그인참여 후 검토

관련 기사

분류에서Dev

Scala 스레드로부터 안전한 랜덤 생성기

분류에서Dev

랜덤 스텝 생성기

분류에서Dev

안드로이드 용 랜덤 부울 생성기

분류에서Dev

테스트를위한 랜덤 생성기 시드

분류에서Dev

랜덤 월드 생성

분류에서Dev

랜덤 월드 생성

분류에서Dev

랜덤 카드 수집 생성기

분류에서Dev

랜덤 카드 수집 생성기

분류에서Dev

랜덤 플로트 생성기

분류에서Dev

스레드로부터 안전한 맵 : 성능 향상

분류에서Dev

랜덤 생성기 질문

분류에서Dev

바우처와 같은 동작을위한 최적의 의사 랜덤 고유 코드 생성기 만들기

분류에서Dev

동일한 시퀀스를 생성하는 랜덤 클래스

분류에서Dev

소수 생성의 랜덤 데이터

분류에서Dev

랜덤 데이터 생성 C #

분류에서Dev

R에서 랜덤 벡터 생성

분류에서Dev

SpriteKit-랜덤 노드 생성

분류에서Dev

랜덤 샘플 데이터 세트 생성기

분류에서Dev

다 정밀도 랜덤 생성기 시드 오류 향상

분류에서Dev

QuickCheck를 사용하여 랜덤 생성기 테스트

분류에서Dev

제공된 (최소한 추정 된) 엔트로피가있는 C ++ 랜덤 생성기

분류에서Dev

가중치 및 편향에 대한 랜덤 벡터 및 행렬 생성

분류에서Dev

R 특정 평균을 중심으로 제한된 랜덤 샘플 생성

분류에서Dev

RAS 알고리즘은 랜덤 매트릭스 생성

분류에서Dev

랜덤 오브젝트의 시드를 랜덤 값으로 설정하면 생성기가 더 랜덤하게 만들어 집니까?

분류에서Dev

랜덤 오브젝트의 시드를 랜덤 값으로 설정하면 생성기가 더 랜덤하게 만들어 집니까?

분류에서Dev

랜덤 포레스트를위한 가능한 알고리즘

분류에서Dev

랜덤 행렬 생성

분류에서Dev

랜덤 이미지 생성

Related 관련 기사

뜨겁다태그

보관