Форум программистов, компьютерный форум, киберфорум
Matlab
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск  
 
 
Рейтинг 4.63/48: Рейтинг темы: голосов - 48, средняя оценка - 4.63
 Аватар для Алексей89
34 / 34 / 4
Регистрация: 19.02.2013
Сообщений: 118

Наладить параллельные вычисления

05.01.2015, 16:13. Показов 10376. Ответов 34

Студворк — интернет-сервис помощи студентам
Вот основной сценарий расчетов, которые мне нужны.
Matlab M
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
function [ Res ] = MainScript(  )
Rin=2;
Rout=2;
CSin1=2;
CSin2=10;%30;
CSout1=2;
CSout2=15;%60;
Res=zeros(CSin2-CSin1+2,CSout2-CSout1+2,2); 
Res(2:size(Res,1),1,1)=CSin1:CSin2;     
Res(1,2:size(Res,2),1)=CSout1:CSout2;   
Res(2:size(Res,1),1,2)=Rin;         
Res(1,2:size(Res,2),2)=Rout;        
for CSin=CSin1:CSin2
    for CSout=CSout1:CSout2
        InHstgrm=getKcndttnHstgrm( Rin, CSin);
        OutHstgrm=getKcndttnHstgrm( Rout, CSout);
        jHyst=HstgrmJunction( InHstgrm, OutHstgrm);
        Res(CSin-CSin1+2,CSout-CSout1+2,:)=StatKmpr(jHyst);
    end    
end
end
Запустил прогу у себя на ноуте (правда с другими параметрами), она считается уже третьи сутки, но занимает при этом только одно ядро (из четырёх). А сессий расчётов предвидится ещё довольно много.
Погуглил как распараллелить вычисления в матлабе, на русском вообще довольно мало написано.

Чтобы топик не выглядел неприлично типа:"Сделайте за меня мою работу", я вкратце опишу основные вопросы и допущения:
Мне представляется, что мою проблему решит parfor, вместо for, если просто дописать, матлаб ругается на переменной Res:"Valid indices for 'Res' are restricted in PARFOR loops". Насколько я понял из небольшой статьи, в параллельном цикле нельзя модифицировать некоторые типы используемых переменных, так гарантируется то, что результаты вычислений в каждой итерации не зависят от результатов из прошлых итераций, в противном случае процесс невозможно запустить параллельно.
Тут возникает правомерный вопрос:
-А как же мне выводить результаты?
В той статье, написано, что: "можно сохранить результаты расчёта в разные ячейки cell-array, и агрегировать результаты после завершения parfor цикла."
-Что это такое и как это сделать?
Кроме того, в упомянутом примере и другой литературе говорится о создании некоего пула. На сколько я понял, пул -это совокупность вычислительных ресурсов, которые участвуют в процессе.
- Необходимо ли открывать Пул при вычислениях с parfor на своём компьютере (без удалённых кластеров)?
- Как ускорить вычисления при помощи видеокарты?
- Для этого годится любая видеокарта, или только со встроенной соответствующей технологией (CUDA или что-то подобное)?

Такие в общем вопросики.
Заранее спасибо!
0
cpp_developer
Эксперт
20123 / 5690 / 1417
Регистрация: 09.04.2010
Сообщений: 22,546
Блог
05.01.2015, 16:13
Ответы с готовыми решениями:

Параллельные вычисления
Имеется код, который проверяет число j на простоту: using System; using System.Collections.Generic; using System.Linq; using...

Параллельные вычисления
Здравствуйте! Нужно перебрать целые числа от M до N и найти первое попавшееся число, подходящее под условие. Это просто решить циклом от M...

Параллельные вычисления
Нужно использовать параллельные вычисления, при решении данной задачи, пробовал распараллелить циклы, но выдавало не верный результат, код...

34
 Аватар для Алексей89
34 / 34 / 4
Регистрация: 19.02.2013
Сообщений: 118
09.01.2016, 12:15  [ТС]
Студворк — интернет-сервис помощи студентам
У себя попробовал такой же код только с
Matlab M
1
matlabpool open 4
И получается
Elapsed time is 0.910913 seconds.
Elapsed time is 0.415450 seconds.
Elapsed time is 1.943877 seconds.
Очевидно для такой задачи векторизация работает эффективнее чем распараллеливание.
parfor покажет более высокую производительность если в теле цикла будет м-функция.
0
0 / 0 / 0
Регистрация: 09.01.2016
Сообщений: 10
09.01.2016, 12:19
Krasme, второй вариант я на подкорку записал, но у меня много обработки в циклах идет. Поэтому хочется разобраться, как эти циклы распараллеливать. Поэтому интересует разница между 1 и 3 вариантом.

У меня просто идет что-то типа статистического моделирования. Идет один большой цикл многократно, а внутри него много маленьких с заданием случайных чисел, их окрасом, добавлением сигнала, фильтрацией и т.п. Фактически, я одно и тоже в верхнем цикле делаю много раз - для набора статистики. Но его, заменой for на parfor, распараллелить не удается - он ругается на то, что не может определить переменные из внутренних циклов.

Вот я и решил мелкие циклы распараллеливать, а толку почему-то нет.
0
 Аватар для Krasme
7960 / 5121 / 2162
Регистрация: 02.02.2014
Сообщений: 13,496
09.01.2016, 12:28
я параллельными вычислениями не занималась, но, как версия, может быть, "циклы в циклах" - не та задача, что удобна для распараллелирования?
0
0 / 0 / 0
Регистрация: 09.01.2016
Сообщений: 10
09.01.2016, 12:32
Krasme, для матлаба может быть, но с точки зрения здравого смысла, что может быть проще, чем распараллелить 500 независимых циклов? Так они по очереди на одном ядре крутятся, а так на 8-ми ядрах.

У меня правда, есть еще одна проблема: на рабочем компе команда matlabpool вообще не работает по не понятной причине, пока тренируюсь на ноуте.
0
 Аватар для Алексей89
34 / 34 / 4
Регистрация: 19.02.2013
Сообщений: 118
09.01.2016, 12:51  [ТС]
У меня была похожая ситуация, распараллеливать внутренние циклы зачастую не выгодно. попробуйте поместить содержимое внешнего цикла в отдельную м-функцию. Тогда ругаться при распараллеливании не должно, правда придётся сразу продумать как потом объединять результаты.
1
0 / 0 / 0
Регистрация: 09.01.2016
Сообщений: 10
09.01.2016, 14:01
Алексей89, как вывести результат я примерно понимаю, у меня после каждого цикла ответ либо 1, либо 0. А общий результат просто усреднение по числу циклов.

Проблема в том, что у меня много входных данных, в том числе матрицы. Матлаб пойдет, что я ему матрицу подсовываю определенного размера или её как-то описывать надо?

Добавлено через 15 минут
Krasme, я выяснил почему операция типа

Matlab M
1
2
3
xj1(1:n)=randn(1,1);
    yi1(1:n)=randn(1,1); 
    zi1=xj1+sqrt(-1)*yi1;
выполняется быстрее
Matlab M
1
2
3
4
5
for i=1:n    
    xj1(i)=randn(1,1); 
    yi1(i)=randn(1,1); 
    zi1(i)=(xj1(i)+sqrt(-1)*yi1(i));
end;
Потому что она присваивает одно и тоже случайное значение в весь массив- не годиться

Добавлено через 9 минут
А если исправить, то примерно тоже самое по времени выходит
0
 Аватар для Krasme
7960 / 5121 / 2162
Регистрация: 02.02.2014
Сообщений: 13,496
09.01.2016, 14:03
верно, мой недогляд
да, и по такому коду
Matlab M
1
2
3
4
5
6
%%
 tic%Начало отсчета
    xj1=randn(1,n);
    yi1=randn(1,n); 
    zi1=xj1+sqrt(-1)*yi1;
toc %Конец отсчета
имею
Matlab M
1
Elapsed time is 0.006004 seconds.
0
 Аватар для Алексей89
34 / 34 / 4
Регистрация: 19.02.2013
Сообщений: 118
09.01.2016, 14:16  [ТС]
Матрица передаваемая в функцию может быть любого размера, главное чтобы функция с ней работала корректно (не запрашивая значений из за пределов таблицы).
Смысл в том, что в один момент времени к массиву имеет доступ только 1 процесс, т.е. если в оперативе один массив, то процессы становятся в очередь, что сьедает почти всю выгоду от распараллеливания.
При вызове же функции, всё что в неё передаётся - копируется в новое место в оперативе.

Проще всего было бы если бы Вы выложили весь свой код а мы его упаковали для parfor.
0
0 / 0 / 0
Регистрация: 09.01.2016
Сообщений: 10
09.01.2016, 14:58
Krasme, те же яйца - вид с боку.

Matlab M
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
close all; clc;
n=1000;
 
tic
xj1(1:n)=randn(1,n);
yi1(1:n)=randn(1,n); 
zi1=xj1+sqrt(-1)*yi1;
RB=0.8; % межпапечная корреляция
AB=sqrt(1-RB^2);
xj2z(1:n)=randn(1,n);
yi2z(1:n)=randn(1,n);
xj2=RB*xj1 + AB*xj2z;
yi2=RB*yi1 + AB*yi2z;
zi2=xj2+sqrt(-1)*yi2;
toc
 
tic
           xj3 = zeros (1,n);
           yj3 = zeros (1,n);
           zj3 = zeros (1,n);
           xj4 = zeros (1,n);
           yj4 = zeros (1,n);
           zj4 = zeros (1,n);
           for i=1:n    
                xj3(i)=randn(1,1); 
                yi3(i)=randn(1,1); 
                zi3(i)=(xj3(i)+sqrt(-1)*yi3(i)); 
           end; 
            
           RB=0.8; % межпапечная корреляция
           AB=sqrt(1-RB^2);
           for i=1:n
                xj4(i)=RB*xj3(i)+AB*randn(1,1);
                yi4(i)= RB*yi3(i)+AB*randn(1,1);
                zi4(i)=(xj4(i)+(sqrt(-1))*yi4(i));
           end;
 toc
Elapsed time is 0.020869 seconds.
Elapsed time is 0.029463 seconds.

Добавлено через 29 минут
Алексей89, я бы с удовольствием весь код выложил, но, к сожалению, специфика работы не разрешает это делать.

В принципе у меня получилось:

Matlab M
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
    tic
    for ww=1:ni%цикл по числу испытаний
        [p1(ww),p2(ww),p3(ww),p4(ww)]= f1(n,d1,d2,d3,lambda,td, vc1, vc2, vm, vvi, LA1, LA2, LA3, LA4, A1, A2, Am1, Am2);
    end ;
    toc 
 
Elapsed time is 2.690068 seconds.
 
    tic
    parfor ww=1:ni%цикл по числу испытаний
        [p1(ww),p2(ww),p3(ww),p4(ww)]= f1(n,d1,d2,d3,lambda,td, vc1, vc2, vm, vvi, LA1, LA2, LA3, LA4, A1, A2, Am1, Am2);
    end ;
    toc 
 
Elapsed time is 1.333250 seconds.
Странно только, что скорость на 4-х ядрах всего в 2 раза быстрее. Это результат на ноуте.
0
 Аватар для Krasme
7960 / 5121 / 2162
Регистрация: 02.02.2014
Сообщений: 13,496
09.01.2016, 15:09
а если переменные сделать глобальными, а не как вход-выход для функции?
0
0 / 0 / 0
Регистрация: 09.01.2016
Сообщений: 10
09.01.2016, 15:30
ALL

мне бы ещё решить проблему с основным компом, где не запускается matlabpool.

Matlab M
1
2
3
4
5
6
7
8
9
10
11
12
13
14
>> matlabpool close
Error using matlabpool (line 147)
matlabpool is not currently active. Use 'matlabpool open' to start an
interactive session. 
>> matlabpool open 4
Warning: Found 1 pre-existing communicating job(s) created by matlabpool that
are pending or queued. You can use 'matlabpool close force local' to remove all
jobs created by matlabpool. 
> In distcomp.interactiveclient.pRemoveOldJobs at 55
  In distcomp.interactiveclient.start at 61
  In MatlabpoolHelper>MatlabpoolHelper.doOpen at 306
  In MatlabpoolHelper>MatlabpoolHelper.doMatlabpool at 137
  In matlabpool at 139 
Starting matlabpool using the 'local' profile ...
Есть какие-нибудь версии по этой проблеме? Матлаб переустанавливал.

Добавлено через 2 минуты
Krasme, не совсем понял. Если они из функции выводятся, разве они не являются глобальными?

Добавлено через 18 минут
Матлаб не разрешает выводит глобальные переменные из функции, даже если ей индекс присваиваю.
0
 Аватар для Алексей89
34 / 34 / 4
Регистрация: 19.02.2013
Сообщений: 118
09.01.2016, 15:37  [ТС]
У меня получилось так:
Исходный вариант
Elapsed time is 0.006782 seconds.
Elapsed time is 0.103077 seconds.

вариант с parfor
Matlab M
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
function [  ] = main(  )
close all; clc;
n=1000;
 
tic
xj1(1:n)=randn(1,n);
yi1(1:n)=randn(1,n); 
zi1=xj1+sqrt(-1)*yi1;
RB=0.8; % межпапечная корреляция
AB=sqrt(1-RB^2);
xj2z(1:n)=randn(1,n);
yi2z(1:n)=randn(1,n);
xj2=RB*xj1 + AB*xj2z;
yi2=RB*yi1 + AB*yi2z;
zi2=xj2+sqrt(-1)*yi2;
toc
 
tic
           xj3 = zeros (1,n);
           yj3 = zeros (1,n);
           zj3 = zeros (1,n);
           xj4 = zeros (1,n);
           yj4 = zeros (1,n);
           zj4 = zeros (1,n);
           parfor i=1:n  
                [xj3(i) yi3(i) zi3(i)]=rnd();
            end; 
            
           RB=0.8; % межпапечная корреляция
           AB=sqrt(1-RB^2);
           parfor i=1:n
                [xj4(i) yj4(i) zj4(i)]=Func(RB, AB, xj3(i), yi3(i));
           end;
 toc
end
function [x y z] = rnd( )
                x=randn(1,1); 
                y=randn(1,1); 
                z=(x+sqrt(-1)*y);
end
function [x y z] = Func(RB, AB, x3,y3)
                x=RB*x3+AB*randn(1,1);
                y= RB*y3+AB*randn(1,1);
                z=(x+(sqrt(-1))*y);
end
Elapsed time is 0.006539 seconds.
Elapsed time is 1.463541 seconds.

Векторизованный вариант
Matlab M
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
function [  ] = main(  )
close all; clc;
n=1000;
 
tic
xj1(1:n)=randn(1,n);
yi1(1:n)=randn(1,n); 
zi1=xj1+sqrt(-1)*yi1;
RB=0.8; % межпапечная корреляция
AB=sqrt(1-RB^2);
xj2z(1:n)=randn(1,n);
yi2z(1:n)=randn(1,n);
xj2=RB*xj1 + AB*xj2z;
yi2=RB*yi1 + AB*yi2z;
zi2=xj2+sqrt(-1)*yi2;
toc
 
tic
%           xj3 = zeros (1,n);
           yj3 = zeros (1,n);
           zj3 = zeros (1,n);
           xj4 = zeros (1,n);
           yj4 = zeros (1,n);
            i=1:n;
            xj3=randn(1,n);
            yi3=randn(1,n);
            zi3(i)=xj3+sqrt(-1).*yi3(i);
 
           RB=0.8; % межпапечная корреляция
           AB=sqrt(1-RB^2);
 
            Rnd1=randn(1,n);
            Rnd2=randn(1,n);
            xj4=RB.*xj3(i)+AB.*Rnd1;
            yi4=RB.*yi3(i)+AB.*Rnd2;
            zi4=xj4(i)+(sqrt(-1)).*yi4(i);
 toc
end
Elapsed time is 0.003431 seconds.
Elapsed time is 0.001149 seconds.

Parfor удобно использовать, когда в цикле больше строк или есть вложенные циклы.
Для этого случая он не нужен
0
0 / 0 / 0
Регистрация: 09.01.2016
Сообщений: 10
09.01.2016, 16:24
Цитата Сообщение от Алексей89 Посмотреть сообщение
У меня получилось так:
Исходный вариант
Elapsed time is 0.006782 seconds.
Elapsed time is 0.103077 seconds.
Не понимаю, почему один и тот же код у всех по разный результат. Точнее у меня отличный результат от других. Вы точно мой вариант пробовали?

По-пробовал на ноуте свой вариант - тоже самое:
Elapsed time is 0.028909 seconds.
Elapsed time is 0.035459 seconds.


Векторный вариант выдает примерно тоже самое.
0
 Аватар для Алексей89
34 / 34 / 4
Регистрация: 19.02.2013
Сообщений: 118
09.01.2016, 16:35  [ТС]
Не знаю с чем это связано, но у меня каждый раз по разному выходит
причём следующие после первого разы на много быстрее:
(Векторизованный вариант)
Elapsed time is 0.000712 seconds.
Elapsed time is 0.000903 seconds.

Исходный вариант точно Ваш.
0
0 / 0 / 0
Регистрация: 09.01.2016
Сообщений: 10
09.01.2016, 16:42
Всё вкурил. Надо через функцию запускать сохраненную, тогда всё ок. А не как я в консоль копировать текст.

Matlab M
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
function [  ] = main(  )
close all; clc;
n=1000;
 
 
tic
xj1(1:n)=randn(1,n);
yi1(1:n)=randn(1,n); 
zi1=xj1+sqrt(-1)*yi1;
RB=0.8; % межпапечная корреляция
AB=sqrt(1-RB^2);
xj2z(1:n)=randn(1,n);
yi2z(1:n)=randn(1,n);
xj2=RB*xj1 + AB*xj2z;
yi2=RB*yi1 + AB*yi2z;
zi2=xj2+sqrt(-1)*yi2;
toc
 
tic
           xj3 = zeros (1,n);
           yi3 = zeros (1,n);
           zi3 = zeros (1,n);
           xj4 = zeros (1,n);
           yi4 = zeros (1,n);
           zi4 = zeros (1,n);
            i=1:n;
            xj3(1:n)=randn(1,n);
            yi3(1:n)=randn(1,n);
            zi3(i)=xj3+sqrt(-1).*yi3(i);
 
           RB=0.8; % межпапечная корреляция
           AB=sqrt(1-RB^2);
 
            Rnd1=randn(1,n);
            Rnd2=randn(1,n);
            xj4=RB.*xj3(i)+AB.*Rnd1;
            yi4=RB.*yi3(i)+AB.*Rnd2;
            zi4=xj4(i)+(sqrt(-1)).*yi4(i);
 toc
 
 tic
           xj5 = zeros (1,n);
           yi5 = zeros (1,n);
           zi5 = zeros (1,n);
           xj6 = zeros (1,n);
           yi6 = zeros (1,n);
           zi6 = zeros (1,n);
           for i=1:n    
                xj5(i)=randn(1,1); 
                yi5(i)=randn(1,1); 
                zi5(i)=(xj5(i)+sqrt(-1)*yi5(i)); 
           end; 
            
           RB=0.8; % межпапечная корреляция
           AB=sqrt(1-RB^2);
           for i=1:n
                xj6(i)=RB*xj5(i)+AB*randn(1,1);
                yi6(i)= RB*yi5(i)+AB*randn(1,1);
                zi6(i)=(xj6(i)+(sqrt(-1))*yi6(i));
           end;
 toc
 
  tic
           for i=1:n    
                xj7(i)=randn(1,1); 
                yi7(i)=randn(1,1); 
                zi7(i)=(xj7(i)+sqrt(-1)*yi7(i)); 
           end; 
            
           RB=0.8; % межпапечная корреляция
           AB=sqrt(1-RB^2);
           for i=1:n
                xj8(i)=RB*xj7(i)+AB*randn(1,1);
                yi8(i)= RB*yi7(i)+AB*randn(1,1);
                zi8(i)=(xj8(i)+(sqrt(-1))*yi8(i));
           end;
 toc
 
end
Elapsed time is 0.000360 seconds.
Elapsed time is 0.000514 seconds.
Elapsed time is 0.011234 seconds.
Elapsed time is 0.014725 seconds.
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
raxper
Эксперт
30234 / 6612 / 1498
Регистрация: 28.12.2010
Сообщений: 21,154
Блог
09.01.2016, 16:42

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

Параллельные вычисления
Прошу помочь решить следующую задачу(параллельное программирование) Дана последовательность чисел. Найти сумму элементов этой...

Параллельные вычисления
Здравствуйте, не знаю в какой ветке постить, решил в этой. Хочу использовать эти технологии OpenMP и\или GPGPU(OpenCL) но практической...

Параллельные вычисления
Здравствуйте. Пишу курсовую,пришлось много что узнавать нового,так как параллельное программирование не изучали вообще. Написал прогу...

Параллельные вычисления средствами С++ 11
Поиск файлов в каталоге реализован в ф-ии direct, потоки управляют из мейна. Ф-ю direct надо разбить на несколько потоков, вывод...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
35
Ответ Создать тему
Новые блоги и статьи
ИИ не может найти нужный язык в списке
Supersumestria 05.10.2026
Я ему даю вот такое изображение и прошу найти и подчеркнуть немецкий язык. Возвращает он вот это: https:/ / i. **********/ vqBWLe2. png Нужную строчку в 3й колонке просто выдумал. . Это. . .
Новая последняя моя музыка в SUNO
zorxor 05.10.2026
Здравствуйте, дорогие мои друзья! С большой радостью я хотел бы представить вам свою новую последнею музыку, которую сгенерировала мне по моей просьбе нейросеть SUNO. С уважением, zorxor. Это. . .
Программный домашний кинотеатр
russiannick 27.09.2026
Сподобился на программный домашний кинотеатр. В качестве ЯВУ по традиции выбрал js. В помощники взял Яндекс-Алису. Было создано три зала на разные интересы. исторические и ретро сериал Хичкок. . .
Беседа с ИИ о программистах, недопускающих к созданию и правке кода генеративные ИИ и причины этого
zorxor 21.09.2026
Раньше я радовался или получал некоторые эмоции, пусть небольшие, но всё же, от самого процесса написания кода, рекомпиляции и запуска, видя постепенное развитие программы и прочее. А теперь лень. . .
Мобильное приложение ColorStep
pavlinmavlin 17.09.2026
Реализовал приложение Красный, Зеленый, Синий в Unity3d + c#. Название изменил на ColorStep. Приложение прошло модерацию и теперь доступно для скачивания. Делал его сам, шаг за шагом — и вот,. . .
Запрет дублирования строк в табличной части
Maks 13.09.2026
Реализация из решения ниже выполнена на нетиповом справочнике "Нормы ТО" с табличной часть "Виды ТО", разработанного в КА2, со следующими реквизитами: - ВидТО (СправочникСсылка. ВидыТО); - ВидГСМ. . .
Скрипты Tampermonkey для CyberForum, ChatGPT, Claude и пр.
Jin X 06.09.2026
Скрипты Tampermonkey для CyberForum, ChatGPT, Claude и пр. Работая с форумом и нейросетями в браузере часто хочется что-то подкорректировать или добавить какого-то функционала. Ниже прикреплён. . .
Программа опроса у.з. расходомера SLS-720F
Argus19 02.09.2026
Программа опроса у. з. расходомера SLS-720F Программа опрашивает один раз в минуту три ультразвуковых расходомера SLS-720F через интерфейс RS-485 по протоколу Modbus RTU. Опрашиваются регистры. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru