exponenta event banner

Несколько потоков

Использование нескольких независимых потоков

Программное обеспечение MATLAB ® включает алгоритмы генератора, которые позволяют создавать несколько независимых потоков случайных чисел. Например, четырьмя типами генераторов, которые поддерживают несколько независимых потоков, являются комбинированные множественные рекурсивные ('mrg32k3a'), Мультипликативный отстающий Фибоначчи ('mlfg6331_64'), Philox 4x32 ('philox4x32_10') и Threefry 4x64 ('threefry4x64_20') генераторы. Можно создать несколько независимых потоков, которые гарантированно не перекрываются и для которых были выполнены тесты, демонстрирующие (псевдо) независимость значений между потоками. Дополнительные сведения о алгоритмах генератора, поддерживающих несколько потоков, см. в таблице алгоритмов генератора в разделе Создание и управление потоком случайных чисел .

RandStream.create функция позволяет создавать потоки, имеющие одинаковый алгоритм генератора и начальное значение, но статистически независимые.

[s1,s2,s3] = RandStream.create('mlfg6331_64','NumStreams',3)
s1 = 
mlfg6331_64 random stream
      StreamIndex: 1
       NumStreams: 3
             Seed: 0
  NormalTransform: Ziggurat
s2 = 
mlfg6331_64 random stream
      StreamIndex: 2
       NumStreams: 3
             Seed: 0
  NormalTransform: Ziggurat
s3 = 
mlfg6331_64 random stream
      StreamIndex: 3
       NumStreams: 3
             Seed: 0
  NormalTransform: Ziggurat

В качестве доказательства независимости можно видеть, что эти потоки в значительной степени некоррелированы.

r1 = rand(s1,100000,1);
r2 = rand(s2,100000,1); 
r3 = rand(s3,100000,1);
corrcoef([r1,r2,r3])
ans = 3×3

    1.0000    0.0007    0.0052
    0.0007    1.0000    0.0000
    0.0052    0.0000    1.0000

В зависимости от приложения, создание только некоторых потоков в наборе независимых потоков может быть полезным, если необходимо смоделировать некоторые события. Укажите StreamIndices для создания только некоторых потоков из множества потоков. StreamIndex возвращает индекс каждого создаваемого потока.

numLabs = 256;
labIndex = 4;
s4 = RandStream.create('mlfg6331_64','NumStreams',numLabs,'StreamIndices',labIndex)
s4 = 
mlfg6331_64 random stream
      StreamIndex: 4
       NumStreams: 256
             Seed: 0
  NormalTransform: Ziggurat

Для проверки точности моделирования можно использовать несколько потоков, поскольку они статистически независимы. Например, набор независимых потоков может быть использован для повторения моделирования Монте-Карло несколько раз в различных сессиях MATLAB или на различных процессорах и определения дисперсии результатов. Это делает несколько потоков полезными в крупномасштабном параллельном моделировании.

Использование начальных значений для получения других результатов

Для типов генераторов, которые явно не поддерживают независимые потоки, различные начальные числа обеспечивают метод создания нескольких потоков. Используя различные начальные значения, можно создавать потоки, которые возвращают различные значения и действуют отдельно друг от друга. Однако использование генератора, специально разработанного для нескольких независимых потоков, является лучшим вариантом, поскольку статистические свойства потоков были тщательно проверены.

Создайте два потока с различными начальными числами с помощью генератора твистера Мерсенна.

s1 = RandStream('mt19937ar','Seed',1)
s1 = 
mt19937ar random stream
             Seed: 1
  NormalTransform: Ziggurat
s2 = RandStream('mt19937ar','Seed',2)
s2 = 
mt19937ar random stream
             Seed: 2
  NormalTransform: Ziggurat

Используйте первый поток в одном сеансе MATLAB для генерации случайных чисел.

r1 = rand(s1,100000,1);

Используйте второй поток в другом сеансе MATLAB для генерации случайных чисел.

r2 = rand(s2,100000,1);

При различных начальных числах потоки обычно возвращают некоррелированные значения.

corrcoef([r1,r2])
ans = 2×2

    1.0000    0.0030
    0.0030    1.0000

Два потока с различными затравками могут показаться некоррелированными, поскольку пространство состояния Мерсенна Твистера намного больше (219937 элементов), чем количество возможных затравок (232). Вероятность перекрытия в различных прогонах моделирования довольно мала, если не использовать большое количество различных начальных значений. Использование широко разнесенных семян не увеличивает уровень случайности. Фактически, доведение этой стратегии до крайности и повторное назначение генератора перед каждым вызовом может привести к последовательности значений, которые не являются статистически независимыми и одинаково распределены.

Заполнение потока наиболее полезно, если он используется в качестве шага инициализации, возможно, при запуске MATLAB или перед запуском моделирования.

Использование субпотоков для получения других результатов

Другим способом получения различных результатов из потока является использование субпотоков. В отличие от начальных чисел, где местоположения вдоль последовательности случайных чисел точно не известны, расстояние между субпотоками известно, поэтому любая вероятность перекрытия может быть исключена. Как и независимые параллельные потоки, были проведены исследования для демонстрации статистической независимости между субпотоками. Короче говоря, субпотоки являются более контролируемым способом выполнения многих из тех же вещей, для которых традиционно использовались затравки, и более легким решением, чем параллельные потоки.

Субпотоки обеспечивают быстрый и простой способ получения различных результатов из одного и того же кода в разное время. Например, создать несколько случайных чисел в цикле.

defaultStream = RandStream('mlfg6331_64');
RandStream.setGlobalStream(defaultStream)
for i = 1:5
    defaultStream.Substream = i;
    z = rand(1,i)
end
z = 0.6986
z = 1×2

    0.9230    0.2489

z = 1×3

    0.0261    0.2530    0.0737

z = 1×4

    0.3220    0.7405    0.1983    0.1052

z = 1×5

    0.2067    0.2417    0.9777    0.5970    0.4187

В другом цикле можно создать случайные значения, которые не зависят от первого набора из 5 итераций.

for i = 6:10
    defaultStream.Substream = i;
    z = rand(1,11-i)
end
z = 1×5

    0.2650    0.8229    0.2479    0.0247    0.4581

z = 1×4

    0.3963    0.7445    0.7734    0.9113

z = 1×3

    0.2758    0.3662    0.7979

z = 1×2

    0.6814    0.5150

z = 0.5247

Каждый из этих субпотоков может воспроизводить свою итерацию цикла. Например, можно вернуться к 6-му подпотоку в цикле.

defaultStream.Substream = 6;
z = rand(1,5)
z = 1×5

    0.2650    0.8229    0.2479    0.0247    0.4581

См. также

|

Связанные темы