Справочник функций

Ваш аккаунт

Войти через: 
Забыли пароль?
Регистрация
Информацию о новых материалах можно получать и без регистрации:

Почтовая рассылка

Подписчиков: -1
Последний выпуск: 19.06.2015

Параллельное VS последовательное вычисление

12K
24 октября 2007 года
ANdroid
37 / / 31.03.2006
Предлагаю такую тему. Необходимо опытным путем выяснить границу, после которой параллельное вычисление окажется эффективнее последовательного (она скорее всего должна быть, так как в случае простых задач расходы на создание потоков не окупаются).
Собсно такую задачку мне и задал препод...

В качестве задания предложено использовать перемножение матрицы A (размера MxN) на вектор B (M). На выходе получится матрица C (размер N), где C(i)=A(i,1)*B(i)+...+A(i,n)*B(i). Кстати N возьмем 10.

Мое видение работы программы такое: в главном цикле последовательно, затем параллельно обрабатываются задания. Задания (матрицы A и B) хранятся в бинарных файлах, откуда перед обработкой считываются в дин. массивы. Задания по сложности варьируются от 100х10 до 5000100х10 с шагом 500000 - итого 10 штук.
Но файл 5000100х10 весит около 210 Метров, корректно ли его считывать в оперативную память (ее 256 Мб)?

Так вот, с последовательным все понятно, суть параллельного - создать 10 потоков, каждый из них посчитает i-й элемент C.
Самое главное, что нужно измерить время, само собой не в секундах :), а учитывая "сложность" задачи - даже не в миллисекундах. Я решил измерять в процессорных тактах (через функцию RDTSC).

Сразу вопрос: если выполнять RDTSC на разных машинах (по производительности), то результаты будут сильно отличаться друг от друга, если да то насколько эффективен такой метод подсчета времени выполнения вычисления?

Ниже приведен кусок моего кода, посвященный параллельной обработке. Есть ли какие замечания к подобной реализации? Обратите внимание на начальный и конечный временные штампы. Как их следует расставить, чтобы условия эксперимента были "максимально чистыми"?. На сколько я понял, полное время подсчета одного задания 10 тредами рассчитывается исходя из конечного штампа последнего (штампы снимаются для каждого и сохраняются в MemoryStream).
Код:
...
{ TDynThread - наследуем от TThread }
constructor TDynThread.Create(Num:byte);
begin
  FNum:=Num;  {Номер нити}
  Inherited Create(false);
  Priority:=tpHighest;
end;
 
procedure TDynThread.Execute;
var
  j:LongWord;
begin
  for j:=0 to D-1 do
    c[FNum]:=c[FNum]+Arr.a[j,FNum]*Arr.b[j];
end;
 
procedure TDynThread.DoTerminate;
begin
  CounterGuard.Acquire; {вход в критическую секцию}
  TimeEnd:=DM.RDTSC; {!!Конечный штамп!!}
  MemoryStream.Write(TimeEnd,SizeOf(Comp)); {сохраняем}
  dec(ActiveThreads); {-1 тред}
  if ActiveThreads=0 then
    Finished.SetEvent; {если закончен последний то сигналим главному процессу}
  CounterGuard.Release; {выход из критической секции}
end;
...
procedure TForm1.ExecParallel;
  {Выполнить параллельно}
var
  i:byte;
begin
  if ActiveThreads>0 then
    raise Exception.Create('...');
  for i:=1 to 10 do
    C:=0; {обнуляем C}
  MemoryStream.Clear; {чистим MemoryStream}
  ActiveThreads:=10;
  Finished.ResetEvent;
  TimeBeg:=DM.RDTSC; {!!Начальный штамп!!}
  for i:=1 to 10 do
    TDynThread.Create(i); {Создаем 10 тредов}
  if Finished.WaitFor(20000) <> wrSignaled then {Ждем завешения всех 10}
    raise Exception.Create('...');
end;
...
551
24 октября 2007 года
Pavia
357 / / 22.04.2004
Сама постановка задачи выгледит странна. Хотя.

Цитата:
Но файл 5000100х10 весит около 210 Метров, корректно ли его считывать в оперативную память (ее 256 Мб)?


Весь файл не влезит. Насколько я понимаю в этом и суть что весь файл сразу нельзя загрузить. Отсюда и должна появиться разница в эффективностях алгоритмов.

Цитата:
Сразу вопрос: если выполнять RDTSC на разных машинах (по производительности), то результаты будут сильно отличаться друг от друга, если да то насколько эффективен такой метод подсчета времени выполнения вычисления?



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

12K
24 октября 2007 года
ANdroid
37 / / 31.03.2006
Цитата:
Сама постановка задачи выгледит странна.


Ну такая вот странная задача... надо решить... Или я написал что-то не понятно?:confused:

Цитата:
Насколько я понимаю в этом и суть что весь файл сразу нельзя загрузить. Отсюда и должна появиться разница в эффективностях алгоритмов.


То есть в сам алгоритм должно входить "считывание на ходу" из файла, например построчно?
А проблемы с блокировками данных при параллельной работе нитей возможны? Какие ограничения на доступ ставить в этом случае? Работаю через FileStream.

Цитата:

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


То есть в принципе этим можно пренебречь?

551
24 октября 2007 года
Pavia
357 / / 22.04.2004
Я в начале не мог зацепиться откуда возьмется обгон одного алгоритма другим. Потом понял что это связанно с чтением файла. Другого я не вижу. Если файл загнать в память то расходы на создание потоков и переключения между ними никогда не окупяться на однопроцессорной системе. А если на много процессорной, то напротив мала вероятность что линейный когда либы сравниться много процессорной.

Да в алгоритм стоит внести чтение. Собственно поэтому паролельная обработка и должна дать прирост.
Хотя это эксперемент надо делать.

Цитата:
А проблемы с блокировками данных при параллельной работе нитей возможны?

На это не смогу ответить. Надо сматреть, вообщем случии ограничения должны помочь.

Ты эксперемент поставь и узнаешь вообщем случии можно принебречь.

303
25 октября 2007 года
makbeth
1.0K / / 25.11.2004
ANdroid, по порядку:
1. Проблема подсчета времени обычно решается использованием функции GetTickCount (если тебя конечно устроит точность до миллисекунды :) )
2. Проблема с блокировками при доступе к одному файлу из нескольких потоков возникает только при записи в этот файл. Проблем при чтении не должно быть вообще...
В данном случае, для работы с большими объемами данных тебе больше подойдут отображаемые в память файлы - копай в сторону функций CreateFileMapping и MapViewOfFile.
3. Судя по твоему коду, ты присваиваешь вычислительному потоку наивысший приоритет. Тебе не кажется, что это ммм... немного не чесно по отношению к способу с использованием последовательного доступа (если ты, конечно, там также не ставишь высший приоритет)? :)
12K
25 октября 2007 года
ANdroid
37 / / 31.03.2006
makbeth, GetTickCount пробовал... нуль получился на маленьких матрицах... вот и решил взять почувствительнее метод...

...кстати от приоритета (normal или highest) как опыт показал не сильно результаты рознятся...
303
26 октября 2007 года
makbeth
1.0K / / 25.11.2004
Цитата: ANdroid
...кстати от приоритета (normal или highest) как опыт показал не сильно результаты рознятся...


Хм... тогда такое ощущение, что у тебя и правда все упирается в скорость чтения данных с диска.

12K
04 декабря 2007 года
ANdroid
37 / / 31.03.2006
Ладно, вобщем я не стал выдумывать и параллельно считывать данные с диска...
Дело в том, что мой препод уверен, что при работе с памятью реально может наступить момент, когда параллельное вычисление окажется быстрее...


Сразу скажу, что препод не спец по потокам и вычислениям в них... короче я не могу его в этом убедить...[INDENT]
Цитата:
[INDENT]Цитата: [/INDENT][INDENT]Но файл 5000100х10 весит около 210 Метров, корректно ли его считывать в оперативную память (ее 256 Мб)? [/INDENT]Весь файл не влезит. Насколько я понимаю в этом и суть что весь файл сразу нельзя загрузить. Отсюда и должна появиться разница в эффективностях алгоритмов.


На самом деле такой файл считывается в память (512Мб) и комп даже выдает результат... только вот вопрос как он туда считывается? Происходит ли свопинг? Если да, то даст ли это тот же результат (ну или подобный), как в случае с последовательным считыванием. Просто дело в том что время параллельного здесь и правда получается меньше. Мне НАДО это объяснить!

Еще такой вопрос: есть программа, написанная по какому-то примеру из учебника, там вычисляется Пи. Есть 2 потока, время замеряется в секундах (функция Time). Если треды сначала запустить один за другим и суммировать их время, а потом запустить их одновременно, то при одновременной работе получается быстрее на 6 секунд (точность до 9-й цифры после запятой)... короче это препод и использует как аргумент...
Если нужно могу выложить исходник этой программы


[/INDENT]

13K
05 декабря 2007 года
Alex_soldier
102 / / 29.01.2007
В условии задачи сказано, что матрицы нужно считывать из файла?
Если нет, то не стоит и заморачиваться на хранение в памяти - все элементы матриц на ходу забить константами (например единицами).
В этом случае будет видна именно разница в скорости вычислений!
12K
05 декабря 2007 года
ANdroid
37 / / 31.03.2006
константами? а как ты представляешь себе матрицу размером хотя бы 100 на 10 забитую в разделе констант??? а нужно сравнить на разных матрицах... само собой, чтобы параллельно и последовательно работать с одними и теми же матрицами, да и чтобы не генерировать каждый раз новые логичнее всего сохранить в файл
13K
05 декабря 2007 года
Alex_soldier
102 / / 29.01.2007
Спрашиваю еще раз:
В условии задачи сказано, что матрицы нужно считывать из файла?

Если нет, то зачем тебе вообще хранить что-либо?
При перемножении вместо обращения к памяти, используешь константы!
И благополучно замеряешь быстродействие вычислений!
Тебе же нужен хронометраж, а не результат!
12K
05 декабря 2007 года
ANdroid
37 / / 31.03.2006
нет, прямо такое не сказано... но в общем-то я не особо понимаю разницу между считыванием из файла в память, а затем обработку и обработку типизированной константы-массива, которая тоже хранится в памяти, ведь отсчет времени не ведется во время считывания... какая разница???
13K
05 декабря 2007 года
Alex_soldier
102 / / 29.01.2007
Разница в отсутствии лишнего геморроя.
По большому счету вам потребуется только 3 переменные (ячейки, а никакие не массивы) - для эмуляции элементов матриц:
A,B =1, а С считаете 2 способами: циклами или параллельно.
12K
05 декабря 2007 года
ANdroid
37 / / 31.03.2006
кстати я же написал что на сравнительно небольших матрицах (до 1000000х10) параллельное - медленнее, что и требовалось доказать... аномалии возникают на матрицах, которые занимают под 500Мб... тут никакие константы не помогут... мне лишь нужно это объяснить...
12K
05 декабря 2007 года
ANdroid
37 / / 31.03.2006
Цитата: Alex_soldier
Разница в отсутствии лишнего геморроя.


то что уже написано 2 месяца назад не есть лишний геморрой ИМХО...

13K
05 декабря 2007 года
Alex_soldier
102 / / 29.01.2007
Геморрой не имеет срока давности (с).

Вероятно, вы сейчас подошли к пределам доступной памяти.
Издержки пошли из-за необходимости подгрузки файла по частям.
Чем не объяснение?

Если же вы хотите выяснить, где в действительности находится точка смены эффективности, то от издержек необходимо избавляться, анализируя только чистые вычисления.
12K
05 декабря 2007 года
ANdroid
37 / / 31.03.2006
насколько я понял в вашей теории разница лишь в количестве итераций, вместо элементов перемножать нужно единицы?
12K
05 декабря 2007 года
ANdroid
37 / / 31.03.2006
Цитата: Alex_soldier
Если же вы хотите выяснить, где в действительности находится точка смены эффективности, то от издержек необходимо избавляться, анализируя только чистые вычисления.


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

13K
05 декабря 2007 года
Alex_soldier
102 / / 29.01.2007
Цитата: ANdroid
насколько я понял в вашей теории разница лишь в количестве итераций, вместо элементов перемножать нужно единицы?

Разница в отсутствии обращений к файлу (и адресации памяти). Количество итераций вообще не имеет право изменяться для матрицы фиксированного размера.

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

Выяснили для значений до 1000000х10? А тенденцию проанализировали? Быть может разница как раз сокращается.
Поэтому я и рекомендую проверить экспериментально гораздо большие диапазоны на облегченной задаче.

12K
05 декабря 2007 года
ANdroid
37 / / 31.03.2006
Цитата: Alex_soldier
Разница в отсутствии обращений к файлу (и адресации памяти). Количество итераций вообще не имеет право изменяться для матрицы фиксированного размера.



Для одной матрицы да, но за один тест их анализируется несколько штук, все с разным количеством элементов в строке...

12K
05 декабря 2007 года
ANdroid
37 / / 31.03.2006
Вот отчет по тесту, чем не тенденция... задания обозначены числом элементов строки. Это уже без обращений к памяти...
12K
05 декабря 2007 года
ANdroid
37 / / 31.03.2006
однако если это и дает какое-то подтверждение, то как быть с примером, вычисляющим Пи... он на разных машинах дает разные показания:
1. на Celeron D-330 2.67GHz - 1024Mb DDR (2 канала по 512) вычисление с заданной точностью 10 раз подряд без потоков проходит быстрее, чем вычисление 10-ю потоками по 1 Пи одновременно...
2. на Pentium 4 (без HT) 1.7GHz -512Mb RIMM (2 канала по 2х128) - все наоборот...
13K
05 декабря 2007 года
Alex_soldier
102 / / 29.01.2007
Цитата: ANdroid
Вот отчет по тесту, чем не тенденция... задания обозначены числом элементов строки. Это уже без обращений к памяти...

Ну и? Посчитал выборочно соотношение: колеблется от 1,47 до 1,58.
Видимо это потолок, если не увеличить интервал еще.
Так что теперь нужно доказать?

Что на поддержание параллельных потоков расходуются системные ресурсы?

12K
05 декабря 2007 года
ANdroid
37 / / 31.03.2006
да, по этим отчетам все сходится... вопрос в том, что препод в это не верит и приводит мне в пример вычисление Пи... собсно я сейчас по этому и парюсь, почему по-разному на разных компах... там ведь тоже нет адресаций в больших массивах, каждый поток работает со своей группой переменных...
Реклама на сайте | Обмен ссылками | Ссылки | Экспорт (RSS) | Контакты
Добавить статью | Добавить исходник | Добавить хостинг-провайдера | Добавить сайт в каталог