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

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

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

The 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 параметр для создания только некоторых потоков из набора из нескольких потоков. The 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

См. также

|

Похожие темы