Модераторы: Daevaorn

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Распределение вычислений на многоядерном процессор 
V
    Опции темы
SABROG
  Дата 28.12.2009, 21:42 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Hacker
****


Профиль
Группа: Завсегдатай
Сообщений: 2481
Регистрация: 18.9.2006

Репутация: 4
Всего: 91



Заморочился таким вопросом. С каждым днем количество ядер в одном процессоре растет. Языки программирования требуют, чтобы программист сам распределял нагрузку на них. Предположим у нас имеется 4294967295 каких-то операций, нужно это операции распределить по всем ядрам. И я значит делю количество операций на количество ядер таким образом:

Код

4294967295 / 2 = 2147483647,5 (2147483647, 2147483648) Остаток 1
4294967295 / 3 = 1431655765 (1431655765, 1431655765, 1431655765) Остаток 0
4294967295 / 4 = 1073741823,75 (1073741824, 1073741824, 1073741824, 1073741823) Остаток 3
4294967295 / 5 = 858993459 (858993459, 858993459, 858993459, 858993459, 858993459) Остаток 0
4294967295 / 6 = 715827882,5 (715827883, 715827883, 715827883, 715827882 ,715827882) Остаток 3

4294967295 / 2147483648 = 1,9 (1, 1, ... n)  Остаток 2147483647


В скобках я вручную раскинул остаток от деления по операциям. Поэтому нагрузка на ядра будет разной, но эта разница сводится к минимуму. Из последней строчки видно, что при количестве ядер процессора 2147483648 (кто знает, может и будет такое) остаток довольно внушителен и его нужно как-то раскидать по 2147483648 ядрам, чтобы распределить нагрузку. Так как это сделать правильно? Это мне нужно будет в цикле из 2147483648 итераций брать значение остатка, прибавлять по 1 в каждой итерации, после чего уменьшить счетчик доступного остатка и выйти из цикла при достижении его нуля?


--------------------
Национальная группа Russian Federation на QtCentre.
PM MAIL   Вверх
djamshud
Дата 28.12.2009, 22:00 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Пердупержденный
***


Профиль
Группа: Завсегдатай
Сообщений: 1655
Регистрация: 23.11.2009

Репутация: 8
Всего: 39



Во-первых, вы рассуждаете о технологиях будущего, насильно привязывая к ним технологию настоящего (овер9000 ядер и создание потоков циклами(имея очевидно ввиду, что цикл почему-то будет выполняться на одном процессоре)). Во-вторых, очень многие задачи (особенно когда речь идет математике, как в вашем примере, или цикла, который создаст тысячи потоков) отлично распараллеливаются автоматически. Итого: компилятор создает "массив задач" и дает команду процессору, который каждую из них пихает в ядро.

Про ОС я специально не упомянал, чтобы проще изложить мысль.

Наверное будет как-то так.


--------------------
'Cuz I never walk away from what I know is right
Alice Cooper - Freedom
PM   Вверх
SABROG
Дата 28.12.2009, 22:13 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Hacker
****


Профиль
Группа: Завсегдатай
Сообщений: 2481
Регистрация: 18.9.2006

Репутация: 4
Всего: 91



Если говорить о настоящем, то компилятор gcc 4.4.0 ничего не распараллеливает и долго выполняющийся цикл работает только на одном ядре, в итоге в диспетчере задач WindowsXP видна загрузка процессора 50% и один из двух графиков (по количеству ядер) работает на 100% в то время как другой ничего не делает. Если потоки создавать вручную через API ос, то все работает как надо. Если говорить о будущем, то вот эта новость заставляет уже задуматься: http://www.overclockers.ru/hardnews/22739.shtml

Код

4294967295 / 128 = 33554431,9921875 () Остаток 127


127 операций, которые нужно раскидать.


--------------------
Национальная группа Russian Federation на QtCentre.
PM MAIL   Вверх
fry
Дата 28.12.2009, 22:46 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 257
Регистрация: 4.10.2006

Репутация: нет
Всего: 3



ИМХО все формулы лучше писать в символьном представлении, а потом делать (или не делать) пример, а то голова трещит от таких цифр.  smile 
Если я правильно понял из 
Цитата

4294967295 / 128 = 33554431,9921875 () Остаток 127

127 операций, которые нужно раскидать.


(пытался понять первый пост, но получил вместо представления о вопросе еще гору вопросов и боль в голове)

вы приводите пример с 4294967295 задачами и 128 ядрами и получаете 127 задач как остаток.

Итак, если я правильно понял вопрос, то на основании того, что 33554431 >> 1 можно сделать вывод, что конкретный способ распределения оставшихся задач не имеет разницы.

ЗЫ Приведенная формула несколько наивна потому, что:
1) Мало таких областей, где все задачи обрабатываются за некоторое определенное и равное время.
2) Определить список задач, выполняемых за некоторое известное время и использовать его при распределении вычислений между ядрами будет довольно трудно в силу большого числа вариантов и наличия необходимости обслуживания такого алгоритма, сводящее увеличение производительности "на нет".

Для таких вычислений гораздо лучше масштабировать кластерную систему, чем многоядерную (ИМХО, т.к. проблема синхронизации).

PM MAIL   Вверх
VictorTsaregorodtsev
Дата 28.12.2009, 22:53 (ссылка) |    (голосов:3) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 274
Регистрация: 28.7.2006

Репутация: 1
Всего: 8



SABROG, надумана проблема. Чего думать, как распределить остаток, если этот оставшийся объем действий (в данном случае) значительно меньше, чем объем действий, попадающий на каждый проц? На любой проц/ядро кинуть этот остаток - и ни выигрыша в скорости, ни проигрыша, ибо это копейки (повторяю - для указанного числа операций).

Да и распределять "равным" образом - вообще-то не всегда наилучший вариант. Т.к. какой-то проц/ядро притормозит из-за отсутствия данных в памяти, какой-то - из-за многозадачности операционки (которая к этому процу привяжет поток другой задачи), да и в самой программе в зависимости от значений данных потребуется или не потребуется пройти по каким-то веткам условий... Поэтому даже если абсолютно равно распределите - абсолютно одновременно все процы у вас закончат считать в очень и очень редком случае.
Я сам объем обрабатываемых данных по нескольким потокам жестко не делю - "индекс" следующего необработанного блока данных управляется через функцию InterlockedIncrement (мгновенно срабатывающую), потоки сами запрашивают с её помощью индекс след.блока для обработки, всё это приводит к тому, что добивающий остаток данных "запоздавший" поток (в отсутствии его притормаживания со стороны операционки) "запаздывает" именно на время, равное времени обработки ОДНОГО последнего куска данных.
PM MAIL WWW   Вверх
djamshud
Дата 28.12.2009, 22:58 (ссылка) |    (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата


Пердупержденный
***


Профиль
Группа: Завсегдатай
Сообщений: 1655
Регистрация: 23.11.2009

Репутация: 8
Всего: 39



"Новость" совершенно не заставляет задумываться. Запись датируется 2006 годом. Но с большой долей уверенности можно скзать, что к N-ому году, если не появится новой концепции построения процессоров, ядер таки станет 128. Только что об этом задумываться?

Хинт1: уже давным давно есть мультипроцессорные системы, софт под которые успешно пишется или берется готовый;
Хинт2: не знаю, как в gcc 4.4.0, но в 4.4.2 есть поддержка автоматизированной многопоточности openMP;
Хинт3: см. функциональные ЯП, не сиськами едины.

И самое главное! Размышления о gcc 4.4.0 просто превосходно подходят к вопросу "что будет через сто лет, когда может быть появится 2147483648-ядерный проц?!".


--------------------
'Cuz I never walk away from what I know is right
Alice Cooper - Freedom
PM   Вверх
SABROG
Дата 28.12.2009, 23:22 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Hacker
****


Профиль
Группа: Завсегдатай
Сообщений: 2481
Регистрация: 18.9.2006

Репутация: 4
Всего: 91



Задача не надумана, а стоит передо мной. Время выполнения каждой операции чуть ли не константно из-за того, что выполняется однотипная операция над известным размером блока. Обычная операция подсчета контрольной суммы, на скорость которой совершенно никак не влияют значения байтов. Да по прогрессу это видно. Вся процедура занимает не больше 60 секунд на одном ядре.

Моя цель в другом. Я хочу, чтобы программа использовала все доступные процессоры в системе, где бы она не выполнялась, поэтому хочу написать функцию, которая могла бы оперировать значениями типа x = количество операций, y = количество процессоров. На выходе хочу получать распределенный список. Запускать остаток от деления в отдельный (третий) поток не хочу. С моей точки зрения это не правильно, особенно при остатке меньше 10. Правильней - раскидать остаток на доступные процессоры.

Может быть OpenMP и будет всё делать сам, но пока этого нет, а количество ядер на разных процах уже разное.

Цитата

Хинт3: см. функциональные ЯП, не сиськами едины.


Это всё-равно, что сказать выкинь исходники, которые писал последнюю неделю на Си++ и перепиши их на другом языке потому, что там есть вещь, которая сделает что-то за тебя. Меня сейчас интересует не работоспособность программы, она уже есть. Хочу оптимизации, потому эта тема скорее для математиков. Может быть есть у кого какая формула, которая даст распределение без топорной итерации и прибавления по одному, мало ли.


--------------------
Национальная группа Russian Federation на QtCentre.
PM MAIL   Вверх
fry
Дата 28.12.2009, 23:41 (ссылка) |    (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 257
Регистрация: 4.10.2006

Репутация: нет
Всего: 3



Цитата

VictorTsaregorodtsev:....."индекс" следующего необработанного блока данных управляется через функцию InterlockedIncrement (мгновенно срабатывающую), потоки сами запрашивают с её помощью индекс след.блока для обработки.....

Думаю лучше задуматься над этим, чем над составлением списка на каждое ядро.

Система с жестким определением числа потоков будет хуже сбалансирована по нагрузке на каждый поток, если так можно выразиться, чем система, предложенная VictorTsaregorodtsev (я ее тоже придерживаюсь), которая сама себя балансирует. Единственное, что нужно сделать, это породить необходимое число потоков, но это уже другая история....

Это сообщение отредактировал(а) fry - 28.12.2009, 23:42
PM MAIL   Вверх
Фантом
Дата 29.12.2009, 13:21 (ссылка) |  (голосов:3) Загрузка ... Загрузка ... Быстрая цитата Цитата


Вы это прекратите!
***


Профиль
Группа: Участник Клуба
Сообщений: 1516
Регистрация: 23.3.2008

Репутация: нет
Всего: 49



Цитата(SABROG @  28.12.2009,  23:22 Найти цитируемый пост)
Это всё-равно, что сказать выкинь исходники, которые писал последнюю неделю на Си++ и перепиши их на другом языке потому, что там есть вещь, которая сделает что-то за тебя.

А это, вообще говоря, не такой плохой совет.  smile Писать подобные вещи на C++ дольше, чем выкинуть уже написанный код, разобраться с чем-нибудь более подходящим и написать на нем код "с нуля".

PM   Вверх
Lazin
Дата 29.12.2009, 13:41 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 3820
Регистрация: 11.12.2006
Где: paranoid oil empi re

Репутация: 41
Всего: 154



4 триллиона(!!!!!) процессоров, общего назначения, видимо потомков какого-нибудь Pentium-a или Athlon-a, а еще все они программируются вручную, код генерируется компилятором, используется task based параллелизм, автор - отсыпь smile 
да в современных процессорах транзисторов меньше на порядок
PM MAIL Skype GTalk   Вверх
bsa
Дата 29.12.2009, 14:05 (ссылка) |    (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Модератор
Сообщений: 9185
Регистрация: 6.4.2006
Где: Москва, Россия

Репутация: 63
Всего: 196



SABROG, я придерживаюсь идеи высказанной VictorTsaregorodtsev. Только я позволю ее немного переформулировать в классическую. Есть очередь задач. Есть N обработчиков, которые выполняют задачи. Как только обработчик свободен, он берет из очереди задачу и начинает ее выполнять. В итоге, происходит автоматическое оптимальное распределение задач по потокам. В худшем случае, N-1 поток будет ждать выполнения последней задачи одним потоком все время ее исполнения (т.е. когда все потоки завершатся одновременно, а в очереди будет только одна задача). Но это маловероятно.
PM   Вверх
xvr
Дата 29.12.2009, 16:30 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 7046
Регистрация: 28.8.2007
Где: Дублин, Ирландия

Репутация: 60
Всего: 223



Цитата(SABROG @ 28.12.2009,  22:13)
Если говорить о будущем, то вот эта новость заставляет уже задуматься: http://www.overclockers.ru/hardnews/22739.shtml

Вот только Intel пока не в курсе  smile По моим данным работы над проектом ManyCore (именно к ним относились упомянутые процессоры) были свернуты где то года 2 назад.  smile 

PM MAIL   Вверх
SABROG
Дата 29.12.2009, 22:50 (ссылка)    | (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата


Hacker
****


Профиль
Группа: Завсегдатай
Сообщений: 2481
Регистрация: 18.9.2006

Репутация: 4
Всего: 91



Как бы там ни было я написал свою функцию распределения нагрузки и она получилась такая:

Код

    while (remainder--) {
        ++result[i++ % result.size()];
    }


Если будут предложения по оптимизации/усовершенствовании, то буду рад услышать.


--------------------
Национальная группа Russian Federation на QtCentre.
PM MAIL   Вверх
Леопольд
Дата 30.12.2009, 00:12 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 943
Регистрация: 17.6.2009

Репутация: 10
Всего: 13



Цитата(SABROG @  29.12.2009,  22:50 Найти цитируемый пост)
Если будут предложения по оптимизации/усовершенствовании, то буду рад услышать. 

Цитата(bsa @  29.12.2009,  14:05 Найти цитируемый пост)
SABROG, я придерживаюсь идеи высказанной VictorTsaregorodtsev. Только я позволю ее немного переформулировать в классическую. Есть очередь задач. Есть N обработчиков, которые выполняют задачи. Как только обработчик свободен, он берет из очереди задачу и начинает ее выполнять. В итоге, происходит автоматическое оптимальное распределение задач по потокам. В худшем случае, N-1 поток будет ждать выполнения последней задачи одним потоком все время ее исполнения (т.е. когда все потоки завершатся одновременно, а в очереди будет только одна задача). Но это маловероятно. 

bsa, это не худший случай, а банальный простой. 

SABROG, я тоже считаю что надо взять другой алгоритм. По крайней мере решение с очередью выглядит перспективнее в плане производительности. Т.е. есть очередь задач, есть очередь обработчиков. Первый обработчик взял из очереди одну задачу и ушёл её обрабатывать и т.д. Нет задач, очередь обработчиков стоит, ожидает поставку дефицита. Нет обработчиков, задачи валяются на полке, .дожидаются обработчиков. Думаю, саму задачу пополнения очередей тоже можно оформить в виде задач в очереди. Тут, пожалуй, могут оказать неоценимую помощь функторы... Попадалась как-то мне одна статейка, парень сделал функторы, вызов которых сводился к паре ассемблерных инструкций, если память не подводит.

Добавлено @ 00:17
Функторы сами по себе и задача и обработчик одновременно.

Это сообщение отредактировал(а) Леопольд - 30.12.2009, 00:21


--------------------
вопросов больше чем ответов
PM MAIL   Вверх
bsa
Дата 30.12.2009, 14:11 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Модератор
Сообщений: 9185
Регистрация: 6.4.2006
Где: Москва, Россия

Репутация: 63
Всего: 196



SABROG, код у тебя не очень читабельный получился... Через пару недель сам будешь плеваться smile
PM   Вверх
Ответ в темуСоздание новой темы Создание опроса
Правила форума "С++:Общие вопросы"
Earnest Daevaorn

Добро пожаловать!

  • Черновик стандарта C++ (за октябрь 2005) можно скачать с этого сайта. Прямая ссылка на файл черновика(4.4мб).
  • Черновик стандарта C (за сентябрь 2005) можно скачать с этого сайта. Прямая ссылка на файл черновика (3.4мб).
  • Прежде чем задать вопрос, прочтите это и/или это!
  • Здесь хранится весь мировой запас ссылок на документы, связанные с C++ :)
  • Не брезгуйте пользоваться тегами [code=cpp][/code].
  • Пожалуйста, не просите написать за вас программы в этом разделе - для этого существует "Центр Помощи".
  • C++ FAQ

Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Earnest Daevaorn

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C/C++: Общие вопросы | Следующая тема »


 




[ Время генерации скрипта: 0.0865 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.