Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:

Методы Монте-Карло для параллельных вычислений. Учебное пособие

.pdf
Скачиваний:
0
Добавлен:
07.09.2026
Размер:
2 Мб
Скачать
☆
с вероятностью 1
lim
ˆa1(K, t) = a,
t→∞
lim
ˆa1(K, t) = a + O(1/t),
K→∞
lim
¯a(K, t) = a;
t→∞
если существует константа B, такая что τ
6 B с вероятностью 1, и
i,j
если B < t, то
M(¯a(K, t)) = a,
и также с вероятностью 1 будет
lim
¯a(K, t) = a;
K→∞
если существует k > 0, такое что
i,j
|τ
k
) < ∞,
i,j
M(|X
тогда
M(¯a(K, t)) = a + o(t−k),
и с вероятностью 1
lim
¯a(K, t) = a + o(t−k).
K→∞
На содержательном уровне эти свойства означают, что если повышения точности пытаются добиться за счет увеличения числа вычислитель­ных устройств в условиях малого времени моделирования t, то оценка среднего не обязана сходиться к истинному значению M(X) = a.
Улучшить свойства оценки ˆa1(K, t) можно следующим образом. Если на i-м вычислительном устройстве в момент t имеется незавер­шенный процесс моделирования, то позволим ему завершиться и рас­смотрим оценку
Ni(t)+1
K
P
P
X
i,j
. (4.10)
ˆa2(K, t) =
i=1
j=1
K
P
(Ni(t) + 1)
i=1
91
Здесь величины Ni(t) и X
i,1
, X
, . . . являются зависимыми, тем не
i,2
менее из фундаментальных результатов теории восстановления следует равенство
Ni(t)+1
X
X
= M(Ni(t) + 1) M(X).
i,j
j=1
Поэтому при K → ∞ можно применить усиленный закон больших чисел и получить
lim
ˆa2(K, t) = a.
K→∞
Определим случайную величину˜Ni(t) = max{1, Ni(t)} и рас-
смотрим новую оценку
K
X
1
¯a1(K, t) =
K
¯
Xi(˜Ni(t)). (4.11)
i=1
Она отличается от оценок (4.9) и (4.10) тем, что если какое-то вычисли­тельное устройство не успевает завершить генерирования хотя бы одной случайной величины, то время работы этого устройства продлевается до завершения текущего акта генерации. В противном случае, исполь­зуются все полученные к моменту t значения. Оказывается (см. [42, 43]), что оценка ¯a1(K, t) является несмещенной, M ¯a1(K, t) = a и с вероят- ностью 1 имеют место предельные соотношения
lim
¯a1(K, t) = a, lim
t→∞
¯a1(K, t) = a.
K→∞
Введем величину
K
X
ˆσ1(K, t) =
1
1 −K
(¯Xi(˜Ni(t)) −¯a1(K, t))2.
i=1
В работах [42, 43] доказано, что
lim
ˆσ1(K, t) = D(¯Xi(˜Ni(t))
K→∞
с вероятностью 1. Тогда имеет место сходимость по распределению при
K → ∞ величины
√
K(¯a1(K, t) −a)/ˆσ1(K, t)
92
к стандартному нормальному закону. На основании этого факта воз­можно строить доверительный интервал для величины a. При фикси­рованном K положим
˜
¯τ (K, t) =
K
K
X
1
i=1
1
˜
Ni(t)
Ni(t)
X
j=1
τ
i,j
и определим величину
˜
Ni(t)
X
1
˜
j=1
X
2 i,j
− ¯a1(K, t)
2
.
2
ˆσ
(K, t) = ˜τ (K, t)
2

K
K
X
1
Ni(t)
i=1
Тогда
lim
t→∞
2
ˆσ
(K, t) = M(τ
2
i,j
) D(X
i,j
)
с вероятностью 1 и величина
√
Kt(¯a1(K, t) −a)/ˆσ2(K, t)
сходится по распределению при t → ∞ к стандартному нормальному распределению. Это также дает возможность построить доверительный интервал для a.
В качестве примера возьмем задачу приближенного вычисления кратного интеграла
Z
Z
···
| {z }
x1>0, ..., xn>0
x1+...+xn61
x
p1−1 1
···x
Γ(p1+ .. . + pn+ 1)
pn−1 n
Γ(p1) ··· Γ(pn)
dx1···dxn= 1. (4.12)
Пусть случайный вектор X = (X1, X2, . . . , Xn) имеет равномерное распределение в области
D = {(x1, x2, . . . , xn): x1> 0, x2> 0, . . . , xn> 0, x1+x2+. . .+xn6 1}
с плотностью
p(x1, x2, . . . , xn) = n!, (x1, x2, . . . , xn) ∈ D.
Введем функцию
f(x1, x2, . . . , xn) = x
p1−1 1
···x
93
Γ(p1+ .. . + pn+ 1)
pn−1 n
Γ(p1) ··· Γ(pn)Γ(n + 1)
.
Тогда справедливо представление
Z
Z
···
| {z }
x1>0, ..., xn>0
x1+...+xn61
x
p1−1 1
···x
Γ(p1+ .. . + pn+ 1)
pn−1 n
Γ(p1) ··· Γ(pn)
dx1···dxn= M f(X ).
Для получения значений величин X1, X2,. . . , Xnвоспользуемся сле­дующим функциональным преобразованием: пусть независимые вели­чины U1, U2, .. . , Unс равномерным распределением в промежутке (0, 1), расположенные в возрастающем порядке, образуют величины
U
(1)
6 U
6 . . . 6 U
(2)
(n)
,
тогда можно положить
X1= U
, X2= U
(1)
(2)
− U
, . . . , Xn= U
(1)
(n)
− U
(n−1)
.
Мы рассмотрим несколько реализаций метода Монте-Карло для вычисления интеграла. Каждая из реализаций использует версию гене­ратора псевдослучайных чисел с поддержкой нескольких потоков чи­сел. Программа 4.1 содержит текст заголовочного файла и реализации явного обратного конгруэнтного генератора.
Программа 4.1. Явный обратный конгруэнтный генератор с поддержкой нескольких потоков псевдослучайных чисел
1 / / se i c grng .h - о б ъ явл е н и е м н о г опо т о ч но г о явного 2 / / обр а т н о го ко н гру э н т но г о ген е р а т ора 3 / / x[ n ,j ] = i n v (a [ j ] * x [n - 1 , j ] + b [ j ]) m o d m 4 # ifnde f SEICG R N G _H 5 # defin e SEICG R N G _H
6 7 # inc l u d e <cma t h > 8 # inc l u d e <vecto r >
9
10 u s i ng n a mes p a c e std ;
11 12 c l a ss s e icgr n g { 13 ve c t o r < u n s igned > s e e d ; 14 uns i g n e d a , c ; 15 sei c g r n g (); 16 publ i c :
94
17 sei c g r n g ( u n s i gned a , un sign e d c , u n s i gned _seed , 18 int L); 19 float n e x t ( int s n u m ); 20 };
21 22 # endif / / SE I CRN G _ H
23 24 / / se i c grng . cc - р еали з а ц ия 25 / / мн о го п о т очн о г о явн о г о обра т н о г о 26 / / ко н гру э н т но г о ген е р а т ора 27 # inc l u d e "s e i c g rng .h " 28 # inc l u d e "v e c t y pes .h " 29 # inc l u d e <stdi o .h > 30 # inc l u d e <algori t h m >
31 32 / / 33 / / a *( a ^ -1 ) + 2 1 4748 3 6 4 7 * b =1; 34 / /
35 36 i n line 37 i n t i n v m o d ( u n s i gned a ){ 38 i4vec u ={ 1 , 0 , a , 0 } , 39 v = { 0 , 1, ( unsi g n e d )214 7 4 8 3 6 4 7 , 0} , t ; 40 in t q; 41 while ( v . i [2] >0){ 42 q = u .i [ 2 ] / v .i [ 2 ] ; 43 t. v = u . v - ( v .v * ( v 4 s i ){ q , q , q , q } ) ; 44 u. v = v . v ; 45 v. v = t . v ; 46 }; 47 if ( u. i [0] >=0) r e t u rn u . i [ 0 ] ; 48 else { 49 q = u .i [ 0 ] % 21 474 8 3 6 47; 50 r e t u r n 21 4 7 4 836 4 7 + q ; 51 } 52 };
53 54 s eicg r n g : : s e i c grng ( u nsig n e d _a , u n s i gned _c , 55 uns i g n e d _ seed , i n t L ) 56 :a ( _ a ), c( _ c ) 57 { 58 seed . r e s i z e ( L ); 59 fill ( seed . b e g i n ( ) , s e e d . en d () , _s e e d %2 1 4 7 483 6 4 7 );
95
60 };
61 62 f l o at s e icgr n g : : next ( i n t sn u m ){ 63 float a n s = 64 invm o d ( seed [ snum ]* a + a* s num + c ) / 21 4 7 4 836 4 7 . 0; 65 ++ s e e d [ s n u m ] ; 66 retur n an s ; 67 }
В Программе 4.2 приведена процедура оценки интеграла (4.12) с помощью нескольких вычислительных потоков. Именно между пото­ками распределяется цикл в строках 50–62. Находятся оценки матема­тического ожидания J = M f (X) и дисперсии σ2= D f(X) величины f(X) в строках 65, 66. Для контроля точности вычисляется абсолют­ная погрешность |J − J | и стандартная погрешность среднего σ/√n по n реализациям.
Программа 4.2. Вычисление интеграла (4.12) с помощью параллельных пото­ков в библиотеке OpenMP
1 # inc l u d e <vecto r > 2 # inc l u d e <cti m e > 3 # inc l u d e <cstdi o > 4 # inc l u d e <cma t h > 5 # inc l u d e <algori t h m > 6 # inc l u d e <iostream > 7 # inc l u d e <omp . h > 8 # inc l u d e "s e i c g rng .h "
9
10 u s i ng n a mes p a c e std ;
11 12 t ypede f ve c tor < double > dv e c ;
13 14 d o uble f ( d v e c x , dvec p ){ 15 doubl e r es , s u m p ; 16 bool fl = f a l s e ; 17 in t sz = x . size (); 18 re s = 0 . 0 ; 19 sump = 1 . 0 ; 20 fo r ( in t i=0; i < s z ; ++ i ){ 21 res + = ( p [i ] - 1 . 0 ) * l o g ( x [ i]) - l g a m m a ( p [ i ]); 22 su m p + = p [i ] ; 23 };
96
24 re s = e x p ( re s - l g a m m a ( sz + 1 .0)+ l g a m m a ( sump ) ) ; 25 retur n re s ; 26 };
27 28 i n t ma i n ( i n t argc , c h a r * a r g v [ ] ) {
29 30 struc t da t a { 31 u n s i gned in t s e ed , n , d i m ; 32 } s p ;
33 34 sp . s e e d = t i m e ( 0 ) ; 35 sp .n = 1 0 0 0 00; 36 sp . d i m = 5 ; 37 doubl e va l = 0 .0 , v a l 2 = 0. 0 ;
38 39 dvec p ( sp . d i m ); 40 sei c g r n g r n g (17 , 2543 , sp . see d , 41 om p _ge t _ max _ t hre a d s ());
42 43 fo r ( dvec : : i t erat o r it =p . begin (); it ! = p . e n d ( ) ; it + + ) 44 * it = 1 . 4 0 ;
45 46 # pragm a om p pa r alle l sh ared ( r ng ) \ 47 red u c t i on (+: v al , v a l 2 ) 48 { 49 # pragm a om p for 50 for ( int i =0; i < s p .n ; i ++){ 51 dvec x ( sp. dim ) ; 52 for ( int k = 0 ; k < sp . dim ; ++ k ){ 53 x[ k ] = r n g . next ( o m p _g e t _ th r e a d_ n u m ()); 54 }; 55 sort ( x. begin () , x . e nd ()); 56 for ( int j= s p . dim - 1 ; j >0; - - j ){ 57 x[ j ] -= x [ j - 1 ] ; 58 }; 59 doub l e y = f ( x , p ); 60 val += y ; 61 val2 += y *y ; 62 }; // # pragma omp f o r 63 }; / / # p r a g m a o m p pa r alle l
64 65 va l /= s p .n ; 66 val2 = v a l 2 / s p . n - val * val ;
97
67 68 co ut < < " r esult ␣ is ␣ " < < v a l 69 << " ,␣ a bsol u t e ␣ error ␣ is ␣ " < < fabs (val - 1 . 0 ) 70 << " ,␣ s t d . e r r ␣ i s ␣" < < sq r t ( v a l 2 ) / s q r t ( sp . n ) < < e n d l ;
71 72 retur n 0; 73 };
Программа 4.3 демонстрирует пример вычисления интегра­ла (4.12) на вычислительном кластере с помощью технологии MPI. В строке 2 подключается заголовочный файл, содержащий объявле­ния функций MPI. Каждый процессор получает задание в виде за­полненной структуры struct sp, объявленной в строках 25–27. Поля этой структуры содержат начальные данные для генератора псевдо­случайных чисел (seed), число реализаций случайного вектора X (n). Для инициализации вычислительной среды вызывается библиотечная функция MPI_Init, которая, в частности, создает обязательный комму­никатор MPI_COMM_WORLD. Затем последовательно определяется число numproc процессов в этом коммуникаторе (строка 33) и номер текущего процесса, его ранг среди всех процессов в данном коммуникаторе (стро­ка 34). Формированием вычислительного задания занимается процесс с рангом 0 (строки 36–39). Затем заполненная структура с заданием рас­пространяется среди всех процессов в коммуникаторе MPI_COMM_WORLD с помощью функции MPI_Bcast широковещательной рассылки. Строки 44–61 выполняются каждым процессом и в ходе их выполнения каждый процесс находит свою оценку J величины интеграла J в переменной val. В строках 62–63 происходит сбор результатов вычислений: каждый
и эти значения сохраняются в массиве vals. Далее все процессы кроме процесса с рангом 0 завершаются, а последний находит окончательную оценку величины J в строках 64–75 и выводит ее пользователю. В це­лом расчет организован по формуле (4.7). Для учета времени работы программы процесс ранга 0 фиксирует время начала работы (строка
36) и время окончания работы (строка 71).
Программа 4.3. Вычисление интеграла на вычислительном кластере с помо­щью технологии MPI
1 # inc l u d e <vecto r > 2 # inc l u d e <mpi . h > 3 # inc l u d e <cti m e > 4 # inc l u d e <cma t h >
98
5 # inc l u d e <algori t h m > 6 # inc l u d e <iostream > 7 # inc l u d e "s e i c g rng .h "
8 9 u s i ng n a mes p a c e std ;
10 t ypede f ve c tor < double > dv e c ;
11 12 d o uble f ( d v e c x , dvec p ){ 13 doubl e r es , s u m p ; 14 in t sz = x . size (); 15 re s = 0 . 0 ; 16 sump = 1 . 0 ; 17 fo r ( in t i=0; i < s z ; ++ i ){ 18 res + = ( p [i ] - 1 . 0 ) * l o g ( x [ i]) - l g a m m a ( p [ i ]); 19 su m p + = p [i ] ; 20 }; 21 re s = e x p ( re s - l g a m m a ( sz + 1 .0)+ l g a m m a ( sump ) ) ; 22 retur n re s ; 23 };
24 25 s t ruct d ata { 26 in t seed , n , d i m ; 27 } sp ;
28 29 i n t ma i n ( i n t argc , c h a r * a r g v [ ] ) { 30 in t myid , n u mpro c ; 31 cloc k _ t st , et ; 32 MPI _ I n i t ( & argc , & a r g v ) ; 33 MP I _ C omm _ s i ze ( M P I_COM M _ W O RLD , & n u m proc ); 34 MP I _ C omm _ r a nk ( M P I_COM M _ W O RLD , & m y i d ); 35 if ( myid ==0) { 36 st = c l o c k ( ) ; 37 sp . seed = t i m e ( 0 ) ; 38 sp . n = 10 0 0 000/ n u m p roc ; 39 sp . dim = 50; 40 }; 41 MPI _ B c a st (( c h a r * ) & sp , si z e of ( sp ) , 42 MP I_CHAR , 0 , MP I_C O M M _W O R L D );
43 44 sei c g r n g r n g (17 , 25 43+1 7 * myid , sp . see d , 1); 45 dvec x ( sp . d i m ) , p ( s p . d im ); 46 doubl e va l = 0 .0 , v a l s [ s p . d i m ]; 47 fo r ( dvec : : i t erat o r it =p . begin (); it ! = p . e n d ( ) ; + + i t )
99
48 * it = 1 . 4 0 ;
49 50 fo r ( in t i=0; i < s p . n ; i ++){ 51 for ( int k =0; k < s p . d i m ; ++ k ) 52 x[k ] = r ng . n e x t ( 0 ) ; 53 so r t (x . beg i n () , x. e n d ( ) ) ; 54 for ( int j = sp . d im - 1 ; j > = 0 ; -- j ) 55 x[j ] -= x [ j - 1 ] ; 56 val + = f ( x , p ); 57 }; 58 va l /= s p .n ; 59 co ut < < " M y ␣ Id ␣ is : ␣ " < < m y i d 60 << " ,␣ l o c al ␣ r e s u l t ␣ is ␣ " << val 61 << " ,␣ a bsol u t e ␣ error ␣ is ␣ " < < fabs (val -1.0) < < endl ; 62 MPI _ G a the r (& v al , 1 , M PI_DOUBLE , vals , 63 1, MPI_ D O U B L E , 0 , MP I _C O M M _WO R L D ) ; 64 if (0 == m y i d ) { 65 for ( int j =1; j < nump r o c ; ++ j ) 66 vals [0] += v a l s [ j ]; 67 va l s [0] / = ( do u b l e ) num p r o c ; 68 cout < < " F i n a l ␣ est i m a t e ␣ is ␣ " << v a ls [ 0 ] 69 << " ,␣ a bsol u t e ␣ error ␣ is ␣ " < < fabs ( v a l s [ 0 ] - 1 . 0 ) 70 << endl ; 71 et = c l o c k ( ) ; 72 cout < < " Time ␣ e l apsed :␣ " 73 < <( double (et - st ))/ CL O C K S_P E R _ SE C 74 << e n d l ; 75 }; 76 MP I _ F ina l i z e (); 77 retur n 0; 78 };
Для компиляции в среде mpich необходимо выполнить команду “mpiCC -o mcint mcint.cc seicgrng.cc”. Результаты запуска с одним вычислительным процессом (командой “ mpirun -np 1 mcint”) и с дву­мя вычислительными процессами (командой “mpirun -np 2 mcint”) на компьютере с процессором AMD Athlon 64 X2 Dual Core Processor 6000+ дают время работы в 32,87 секунды и 16,52 секунды соответственно, то есть достигнуто двукратное ускорение работы программы в соответ­ствии со вторым законом Амдала [2].
Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]