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

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

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

Author24 — интернет-сервис помощи студентам
Вот основной сценарий расчетов, которые мне нужны.
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
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
05.01.2015, 16:13
Ответы с готовыми решениями:

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

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

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

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

34
318 / 257 / 30
Регистрация: 30.03.2013
Сообщений: 755
05.01.2015, 17:29 2
Лучший ответ Сообщение было отмечено Алексей89 как решение

Решение

Можно привести работающий код, с данными и вызовом функции из основной программы ?

Обычно распаралеливание - не выход, и лучше обычно двигаться в сторону векторизации кода.
0
34 / 34 / 4
Регистрация: 19.02.2013
Сообщений: 118
05.01.2015, 19:07  [ТС] 3
Частично разобрался с 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
function [ Res ] = MainScript(  )
Rin=2;
Rout=4;
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;
matlabpool open 2
tic;
for CSin=CSin1:CSin2
    parfor CSout=CSout1:CSout2
        InHstgrm=getKcndttnHstgrm( Rin, CSin);
        OutHstgrm=getKcndttnHstgrm( Rout, CSout);
        jHyst=HstgrmJunction( InHstgrm, OutHstgrm);        
        tmpRes(CSin,CSout,:)=StatKmpr(jHyst);
    end    
end
toc;
Res(2:CSin2-CSin1+2,2:CSout2-CSout1+2,:)=tmpRes(CSin1:CSin2,CSout1:CSout2,:);
matlabpool close
end
Вопрос с видеокарточкой остаётся открытым. Для меня это очень актуально, т.к. на стационарном ПК у меня только 2 ядра ЦП, зато 2 слота под видео.

Обычно распаралеливание - не выход, и лучше обычно двигаться в сторону векторизации кода.
Ну, желаемый результат я отчасти получил, а код вложенных функций я приводить не буду, скажу только, что он сплошь состоит из циклов, в которых каждый результат зависит от предыдущих итераций.
0
533 / 438 / 47
Регистрация: 17.07.2013
Сообщений: 2,236
07.01.2015, 21:32 4
С применением видеокарт не все так просто. В принципе, любая современная видеокарта (с поддержкой определенной версии CUDA) может ускорить расчеты, но не каждая поддерживает функцию коррекции ошибок, кажется, этот алгоритм называется ЕЕС или ЕСС. Для расчета картинки неправильный расчет одного пикселя может быть визуально и не заметен, а для серьезных расчетов этот вопрос требует проверки. В прошлом году я консультировался с NVIDIO и в результате я взял TITAN. Может быть сейчас еще что-то появилось.

Добавлено через 4 минуты
Я буду в Москве после 12 января, могу прогнать Ваш тестовый пример с TITAN и без него.
1
318 / 257 / 30
Регистрация: 30.03.2013
Сообщений: 755
07.01.2015, 21:55 5
У меня стоит даже 2 GpuDevice Nvidia, но проблема в том, что список функций Матлаба, которые поддерживают GPU очень скромный
([URL="http://http://www.mathworks.com/help/distcomp/run-built-in-functions-on-a-gpu.html"])

и для классификации там ничего нет.

Поэтому пробуем делать пока на PGI Fortran, и тоже не очень успешно ...
1
34 / 34 / 4
Регистрация: 19.02.2013
Сообщений: 118
08.01.2015, 00:18  [ТС] 6
Nick07, большое спасибо за предложение, но я так примерно и понял уже, что судя по видеообзору для видеокарточки нужен специфический код.
Пока топлю кухню процом от ноута, в принципе спешить мне некуда, а пока считается я, как советовал sergsh, переделываю некоторые функции (по возможности) под векторные операции.
Об относительном приросте производительности я ещё напишу, когда закончу, а тему, я так понимаю пока можно считать закрытой.
0
533 / 438 / 47
Регистрация: 17.07.2013
Сообщений: 2,236
08.01.2015, 18:16 7
Лучший ответ Сообщение было отмечено Алексей89 как решение

Решение

1. Прежде всего надо "зафиксировать" размеры матриц, типа: A = ones ( 1000, 100 )
2. Векторизация безусловно ускоряет вычисления, но на моих данных при переходе на векторизацию проявилась нехватка памяти и пришлось вернуться на обычный цикл.

Добавлено через 3 минуты
Посмотрите стр 243, да и вся книга довольно интересна:
_Дьяконов А Г АНАЛИЗ ДАННЫХ MATLAB ВМК МГУ 2010
я выкладывал ссылку на эту книгу

Добавлено через 29 минут
И это также интересно, и сама книга и ссылка на сайт, где описываются недокументированные возможности:
Accelerating MATLAB Performance source files
http://www.mathworks.com/matla... urce-files
1
318 / 257 / 30
Регистрация: 30.03.2013
Сообщений: 755
09.01.2015, 01:04 8
Векторизация безусловно ускоряет вычисления, но на моих данных при переходе на векторизацию проявилась нехватка памяти и пришлось вернуться на обычный цикл.

Не хватает ОЗУ или памяти видеокарты ?
0
533 / 438 / 47
Регистрация: 17.07.2013
Сообщений: 2,236
10.01.2015, 11:39 9
ОЗУ, но это для МОЕЙ задачи и при моих 32 Gb. Пришлось менять алгоритм. Вполне возможно, что при векторизации для Вашей задачи всего хватит.
0
34 / 34 / 4
Регистрация: 19.02.2013
Сообщений: 118
11.01.2015, 02:30  [ТС] 10
Ну, что сказать, после всесторонней оптимизации, тот пример, что считался почти трое суток, теперь на одном ядре прогоняется за четверть секунды.
За книжку большое спасибо! когда без лишних переливаний есть чёткий набор конкретных рекомендаций, это всегда удобно.
Так что всем большое спасибо!
Тема закрыта
0
533 / 438 / 47
Регистрация: 17.07.2013
Сообщений: 2,236
11.01.2015, 10:46 11
Цитата Сообщение от Алексей89 Посмотреть сообщение
после всесторонней оптимизации
Да рано тему закрывать - самое интересное началось!
А что помогло: изменение алгоритма (подозреваю, что это) или какие игры с MATLAB?
0
34 / 34 / 4
Регистрация: 19.02.2013
Сообщений: 118
11.01.2015, 14:29  [ТС] 12
Да, надо сказать, когда я писал код в первый раз, думал не о скорости, а о том, как не допустить систематической ошибки, чтобы всё считалось верно.
А когда подошёл к написанию с позиции оптимизации, оказалось что самый верный рецепт - это не удалять данные которые ещё хоть раз могут пригодиться, так например, вначале темы я приводил цикл:
Matlab M
1
2
3
4
5
6
7
8
9
10
tic;
for CSin=CSin1:CSin2
    for CSout=CSout1:CSout2
        InHstgrm=getKcndttnHstgrm( Rin, CSin);
        OutHstgrm=getKcndttnHstgrm( Rout, CSout);
        jHyst=HstgrmJunction( InHstgrm, OutHstgrm);        
        tmpRes(CSin,CSout,:)=StatKmpr(jHyst);
    end    
end
toc;
Мне тогда глаз не резануло, что функция getKcndttnHstgrm зависит в первом случае от внешнего итератора, а во втором случае от внутреннего.
Сейчас этот кусочек скрипта выглядит так:
Matlab M
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
InHstgrm=getRdynKcndttnHstgrm( RdynIn, LCSTabIn, CSin1 );  
InHstgrmSet=zeros(size(InHstgrm,1),size(InHstgrm,2),CSin2-CSin1+1); 
InHstgrmSet(:,:,1)=InHstgrm;        
for CSin=CSin1+1:CSin2          
   InHstgrmSet(:,:,CSin-CSin1+1)=getRdynKcndttnHstgrm( RdynIn, LCSTabIn, CSin );    
end
OutHstgrm=getRdynKcndttnHstgrm( RdynOut, LCSTabOut, CSout1 );   
OutHstgrmSet=zeros(size(OutHstgrm,1),size(OutHstgrm,2),CSout2-CSout1+1); 
OutHstgrmSet(:,:,1)=OutHstgrm;       
for CSout=CSout1+1:CSout2          
   OutHstgrmSet(:,:,CSout-CSout1+1)=getRdynKcndttnHstgrm( RdynOut, LCSTabOut, CSout );    
end
for CSin=CSin1:CSin2    
    for CSout=CSout1:CSout2        
        jHyst=HstgrmJunction( InHstgrmSet(:,:,CSin-CSin1+1), OutHstgrmSet(:,:,CSout-CSout1+1));        
        tmpRes(CSin,CSout,:)=StatKmpr(jHyst);
    end    
end
И таких моментов я нашёл у себя довольно много, но в следующий раз буду уже наученный. Наверное, из таких маленьких личных открытий и складывается багаж опыта.
0
533 / 438 / 47
Регистрация: 17.07.2013
Сообщений: 2,236
11.01.2015, 14:51 13
Цитата Сообщение от Алексей89 Посмотреть сообщение
таких маленьких личных открытий и складывается багаж опыта.
и таких важных!
0
0 / 0 / 0
Регистрация: 09.01.2016
Сообщений: 10
09.01.2016, 00:31 14
Помогите и мне понять что происходит при использовании параллельных вычислений. У меня время вычислений значительно возрастает.

Код примитивный:
Matlab M
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
tic%Начало отсчета
n=1000000;
for i=1:n    
    xj1(i)=randn(1,1); 
    yi1(i)=randn(1,1); 
    zi1(i)=(xj1(i)+sqrt(-1)*yi1(i)); 
end;
toc %Конец отсчета
 
tic%Начало отсчета
n=1000000;
parfor i=1:n    
    xj1(i)=randn(1,1); 
    yi1(i)=randn(1,1); 
    zi1(i)=(xj1(i)+sqrt(-1)*yi1(i)); 
end;
toc %Конец отсчета


А вот результат:
Elapsed time is 6.453469 seconds.
Elapsed time is 42.462830 seconds.

Получается что расчет на 4-х ядрах в 7 раз медленнее, чем на одном. Поясните - как такое получается?

З.Ы. matlabpool запущен
0
6922 / 4963 / 2096
Регистрация: 02.02.2014
Сообщений: 13,192
09.01.2016, 01:38 15
у меня получился другой результат
Кликните здесь для просмотра всего текста
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
clc; clear all;
tic%Начало отсчета
n=100000;
for i=1:n    
    xj1(i)=randn(1,1); 
    yi1(i)=randn(1,1); 
    zi1(i)=(xj1(i)+sqrt(-1)*yi1(i));
end;
toc %Конец отсчета
%%
 tic%Начало отсчета
    xj1(1:n)=randn(1,1);
    yi1(1:n)=randn(1,1); 
    zi1=xj1+sqrt(-1)*yi1;
toc %Конец отсчета
%%
matlabpool open
tic%Начало отсчета
parfor i=1:n    
    xj1(i)=randn(1,1); 
    yi1(i)=randn(1,1); 
    zi1(i)=(xj1(i)+sqrt(-1)*yi1(i)); 
end;
toc %Конец отсчета
matlabpool close
результат
Elapsed time is 50.439199 seconds.
Elapsed time is 0.001857 seconds.
Starting matlabpool using the 'local' configuration ... connected to 2 labs.
Elapsed time is 1.218348 seconds.
Sending a stop signal to all the labs ... stopped.
>>

1
533 / 438 / 47
Регистрация: 17.07.2013
Сообщений: 2,236
09.01.2016, 09:12 16
Для начала между 2-й и 3-й строками зарезервируйте память для своих векторов/матриц, типа:
xj1 = zero (xj1(n) ) ;

Добавлено через 2 минуты
См. стр. 243
_Дьяконов А Г АНАЛИЗ ДАННЫХ MATLAB ВМК МГУ 2010 г 278 стр
1
0 / 0 / 0
Регистрация: 09.01.2016
Сообщений: 10
09.01.2016, 12:03 17
Krasme, запустил Ваш код в 2012 версии:

Elapsed time is 0.780846 seconds.
Elapsed time is 0.054563 seconds.
Starting matlabpool using the 'local' profile ... connected to 4 workers.
Elapsed time is 2.417867 seconds.
Sending a stop signal to all the workers ... stopped.

Немного убивает разница в цифрах, не только в скорости параллельных вычислений, но и первая цифра у Вас очень большая.

Вопрос, почему у Вас пишет connected to 2 labs, а у меня connected to 4 workers. Вы не на ядра распараллеливаете, а на другие машины?

Добавлено через 9 минут
Nick07, заметно лучше стали параллельные вычисления. Но всё равно медленнее однопоточного.

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
clc; clear all;
tic%Начало отсчета
n=100000;
xj1 = zeros (1,n);
yj1 = zeros (1,n);
zj1 = zeros (1,n);
for i=1:n    
    xj1(i)=randn(1,1); 
    yi1(i)=randn(1,1); 
    zi1(i)=(xj1(i)+sqrt(-1)*yi1(i));
end;
toc %Конец отсчета
%%
 tic%Начало отсчета
    xj1(1:n)=randn(1,1);
    yi1(1:n)=randn(1,1); 
    zi1=xj1+sqrt(-1)*yi1;
toc %Конец отсчета
%%
matlabpool open
tic%Начало отсчета
parfor i=1:n    
    xj1(i)=randn(1,1); 
    yi1(i)=randn(1,1); 
    zi1(i)=(xj1(i)+sqrt(-1)*yi1(i)); 
end;
toc %Конец отсчета
matlabpool close
Результат:
Elapsed time is 0.784488 seconds.
Elapsed time is 0.001849 seconds.
Starting matlabpool using the 'local' profile ... connected to 4 workers.
Elapsed time is 1.041601 seconds.
Sending a stop signal to all the workers ... stopped.
0
6922 / 4963 / 2096
Регистрация: 02.02.2014
Сообщений: 13,192
09.01.2016, 12:06 18
Little_boo, у меня версия 2010b и двухядерный процессор, ОЗУ 4гб... не знаю, в версии ли дело, у меня вообще на любую задачу матлаб при запуске задумывается, а потом быстро-быстро все и считает, и выводит..
с предопределением массивов у меня все нормально и с первым блоком
Matlab M
1
Elapsed time is 0.415873 seconds.
поправка в коде
Matlab M
1
2
3
xj1 = zeros (1,n);
yi1 = zeros (1,n);
zi1 = zeros (1,n);
0
0 / 0 / 0
Регистрация: 09.01.2016
Сообщений: 10
09.01.2016, 12:11 19
Krasme, наверно, у Вас какой-то глюк на первую операцию. Потому что не может этот цикл на одном ядре выполняться 50 секунд, а время второго варианта и параллельных вычислений у нас примерно одинаковое.

Matlab M
1
Elapsed time is 0.415873 seconds.
а ну вот, так у Вас тоже на одном ядре быстрее, чем на двух
0
6922 / 4963 / 2096
Регистрация: 02.02.2014
Сообщений: 13,192
09.01.2016, 12:14 20
Цитата Сообщение от Little_boo Посмотреть сообщение
время второго варианта и параллельных вычислений у нас примерно одинаковое.
так второй вариант не тратит время на прогон по циклам, а работает, с матрицами, как с простыми переменными..
см. выше, с предопределением массивом и первый вариан стал быстро работать..
0
09.01.2016, 12:14
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
09.01.2016, 12:14
Помогаю со студенческими работами здесь

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

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

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

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


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

Или воспользуйтесь поиском по форуму:
20
Ответ Создать тему
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2024, CyberForum.ru