Гость
Целевая тема:
Создать новую тему:
Автор:
Форумы / C++ [игнор отключен] [закрыт для гостей] / Почему не распараллеливаются потоки / 25 сообщений из 27, страница 1 из 2
28.11.2016, 15:44
    #39356060
Garfish
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Почему не распараллеливаются потоки
Добрый день, коллеги!

Столкнулся с проблемой при распараллеливании вычислений, и не могу понять причину почему потоки не работают параллельно.
Пишу на с++ Builder 6 приложение. Пробовал и на dll перенести в VS 2008, итог одинаковый.

Для запуска в потока использую API Windows CreateThread, количество потоков контролирую семафорами. Отладил потоки сначала на простенькой функции сложения в цикле, поверил запустил все работает, потоки грузят ядра процессора. Как только перенес алгоритм расчета в поток, многопоточность перестала работать, точнее она вроде бы и есть но при работе грузится только 1 процессор.

В поточных расчете используется порядка 7 классов, и операции с данными в этих классах, обход деревьев, разделение деревьев, объединение деревьев, деревья реализованы на вектора std.

Может как то можно отловить кусок кода который препятствует распараллеливанию потоков?
Поделитесь опытом...
...
Рейтинг: 0 / 0
28.11.2016, 15:50
    #39356066
Dima T
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Почему не распараллеливаются потоки
Логи пиши и изучай что каждый поток делает. ID потока GetCurrentThreadId()
...
Рейтинг: 0 / 0
28.11.2016, 16:06
    #39356081
Dimitry Sibiryakov
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Почему не распараллеливаются потоки
GarfishДля запуска в потока использую API Windows CreateThread

"Уже смешно", доки явно не читаны.

GarfishМожет как то можно отловить кусок кода который препятствует
распараллеливанию потоков?
Профилер попробуй.
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
28.11.2016, 17:22
    #39356177
MasterZiv
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Почему не распараллеливаются потоки
GarfishДобрый день, коллеги!

Столкнулся с проблемой при распараллеливании вычислений, и не могу понять причину почему потоки не работают параллельно.
Пишу на с++ Builder 6 приложение. Пробовал и на dll перенести в VS 2008, итог одинаковый.
...

В поточных расчете используется порядка 7 классов, и операции с данными в этих классах, обход деревьев, разделение деревьев, объединение деревьев, деревья реализованы на вектора std.

Может как то можно отловить кусок кода который препятствует распараллеливанию потоков?
Поделитесь опытом...

Это всё очень сложно, и без кода вообще нет смысла обсуждать.
Скоре всего, всё тривиально, и ты просто неправильно диагносцируешь загрузку процессоров.
Но может быть и ты сделал какую-то сериализацию в программе, и потоки друг другу мешают.

Например, что значит вот это вот :
авторДля запуска в потока использую API Windows CreateThread, количество потоков контролирую семафорами. Отладил потоки
?

Количество потоков семафорами невозможно контролировать, семафорами возможно только контролировать кто из запущенных потоков будет работать.


И в идеале это вообще не нужно делать, в идеале многопоточная программа должна выглядеть так:
0) взял всю работу, что нужно сделать, описал её данными.
1) разделил эту работу на куски в соответствии с уровнем параллелизма системы (N кусков)(грубо -- кол-во процессоров).
2) запустил N потоков, каждому из потоков дал свой кусок вычислений.
3) дождался конца выполнения каждого из потоков.
4) для хорошего распаралеливания нужно, чтобы у потоков не было общих выходных данных, а входные были бы только на
чтение. Иначе надо будет синхронизировать доступ к данным, что приведёт неизбежно к состязаниям за этот доступ и
снижению общего уровня параллелизма.
5) в конце все потоки должны отдать результаты и главный поток должен их как-то сагрегировать в единый результат.
...
Рейтинг: 0 / 0
28.11.2016, 17:23
    #39356180
MasterZiv
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Почему не распараллеливаются потоки
Dimitry SibiryakovGarfishДля запуска в потока использую API Windows CreateThread

"Уже смешно", доки явно не читаны.


Ты на beginthread_ex намекаешь ?
Если так, не факт, что он в Builder е есть или если есть, то так же называется.
...
Рейтинг: 0 / 0
28.11.2016, 17:43
    #39356218
Dimitry Sibiryakov
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Почему не распараллеливаются потоки
MasterZivТы на beginthread_ex намекаешь ?
Я намекаю на явное указание "никогда не использовать эту функцию в программах,
использующих RTL".
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
28.11.2016, 18:14
    #39356254
Garfish
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Почему не распараллеливаются потоки
MasterZiv,

по 4 пункту есть общая выходная переменная std::vector по окончании вычислений объем больше 1 гига, результаты всех потоков записываются в структуру и передаются в вектор

спасибо есть интересные идеи будем думать
...
Рейтинг: 0 / 0
28.11.2016, 21:04
    #39356366
MasterZiv
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Почему не распараллеливаются потоки
Dimitry SibiryakovMasterZivТы на beginthread_ex намекаешь ?
Я намекаю на явное указание "никогда не использовать эту функцию в программах,
использующих RTL".



ну это одно и то же.
на самом деле можно, если в этом созданном потоке CRT не использовать...
...
Рейтинг: 0 / 0
28.11.2016, 21:06
    #39356369
MasterZiv
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Почему не распараллеливаются потоки
Garfish,

тебе думать не надо, тебе надо код опубликовать, если хочешь, чтобы тебе помогли...
...
Рейтинг: 0 / 0
29.11.2016, 10:30
    #39356599
Garfish
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Почему не распараллеливаются потоки
MasterZiv,

сделал ведение лога по прохождению функции и записью Id процесса, процессы работают параллельно но в пределах одного ядра.
начал отключать куски кода, и нашел что распараллеливание пропадает при подключении сборки дерева на рекурсивном вызове new
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
void node::node(vector<csgjs_polygon> &list)
{
...
if (!front) front = new node(list_front);
if (!back) back= new node(list_back);
...
}


сли исходить из такой логики, что потоки работают в одном адресном пространстве программы, то работа с общей памятью при выделении памяти происходит в "одно окно"
...
Рейтинг: 0 / 0
29.11.2016, 13:00
    #39356762
Siemargl
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Почему не распараллеливаются потоки
Запросто.

Есть многопоточные аллокаторы, но если ты хочешь быструю программу - старайся уйти от постоянных мелких выделений памяти.
...
Рейтинг: 0 / 0
29.11.2016, 13:16
    #39356777
MasterZiv
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Почему не распараллеливаются потоки
GarfishMasterZiv,

сделал ведение лога по прохождению функции и записью Id процесса, процессы работают параллельно но в пределах одного ядра.
начал отключать куски кода, и нашел что распараллеливание пропадает при подключении сборки дерева на рекурсивном вызове new
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
void node::node(vector<csgjs_polygon> &list)
{
...
if (!front) front = new node(list_front);
if (!back) back= new node(list_back);
...
}


сли исходить из такой логики, что потоки работают в одном адресном пространстве программы, то работа с общей памятью при выделении памяти происходит в "одно окно"


сказки не рассказывай.

впрочем, если у тебя билдер, и там может ты собрал с однопоточной CRT, и она там сделана так, что на всякий случай ставит process affinity mask на один проц, то ты вполне можешь получить такую картину.

это все предположение, я билдер не знаю, и знаю не хочу, и тебе не советую.
...
Рейтинг: 0 / 0
29.11.2016, 20:30
    #39357289
Garfish
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Почему не распараллеливаются потоки
MasterZiv,

проблема в new как я и предполагал, когда используется new работа с общим адресным пространством программы работает в одно окно, я сделал простенький проект с многопоточностью.
В нем 2 функции, Первая MulAdd1 без использования new, все распараллеливается на 4 ядра.
И вторая функция MulAdd2 где используется оператор new многопоточность исчезает.

посмотри пожалуйста, как можно распараллелить потоки по ядрам не изменяя код функции MulAdd2

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
DWORD WINAPI ThreadRoutine(LPVOID Param)
{
	HANDLE hSemaphore = OpenSemaphore( SEMAPHORE_ALL_ACCESS,0 ,lpSemaphoreName);//открываем семафор

  MulAdd1();//потоки грузят 4 ядра
 // MulAdd2();//работает в один поток
  
	ReleaseSemaphore(hSemaphore, 1, NULL);//освобождаем семафор
  CloseHandle(hSemaphore);
	ExitThread(0);
	return 0;
}
...
Рейтинг: 0 / 0
29.11.2016, 20:41
    #39357293
Dimitry Sibiryakov
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Почему не распараллеливаются потоки
Garfishкак можно распараллелить потоки по ядрам не изменяя код функции MulAdd2

Ну, например, можно переопределить операторы new и delete объектов, которые там
выделяются-освобождаются так, чтобы они были более thread-friendly.
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
29.11.2016, 20:54
    #39357298
Garfish
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Почему не распараллеливаются потоки
Dimitry Sibiryakov,

а как?
new вызывается в конструкторе класса
delete в деструкторе

и принцип работы такой, что я обхожу по узлам деревья и строю новое node->node->node->node-> .... node->node->node->end

можно это решить как то за пределами функции использующей выделение памяти, что бы для каждого потока задать свое адресное пространство?
...
Рейтинг: 0 / 0
29.11.2016, 21:21
    #39357309
Garfish
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Почему не распараллеливаются потоки
Siemargl,

многопоточный аллокатор, как его сделать? ни разу не сталкивался, но похоже это то, что надо в моем случае
...
Рейтинг: 0 / 0
29.11.2016, 22:02
    #39357322
Siemargl
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Почему не распараллеливаются потоки
Garfish,

Трай гуггл зис, Люк!
...
Рейтинг: 0 / 0
29.11.2016, 22:16
    #39357329
SashaMercury
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Почему не распараллеливаются потоки
Garfish,

проблема может быть не в какой-то синтаксической ошибке или качестве вашего кода, а в том, что разработанная программа не реентерабельна в целом
...
Рейтинг: 0 / 0
29.11.2016, 22:25
    #39357332
Garfish
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Почему не распараллеливаются потоки
SashaMercury,

как в потоках реализовать разделяемое адресное пространство не знаю, но вот используя разделяемую память можно запустить разные процессы и читать данные в разделяемой памяти, процессы будет между собой изолированы на работу с памятью но будет общая точка обмена данными разделяемая память, пока что я вижу такую возможность распараллеливания
...
Рейтинг: 0 / 0
30.11.2016, 00:48
    #39357364
MasterZiv
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Почему не распараллеливаются потоки
Garfish,
что проще то выделить память до создания потока, передать в функцию потока, потом удалить?
можно также вообще память не выделять, использовать статическую память, Или выделять через alloca().
...
Рейтинг: 0 / 0
30.11.2016, 09:32
    #39357450
Garfish
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Почему не распараллеливаются потоки
MasterZiv,

а применительно к конструктору node как это можно сделать?

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
void node::node(vector<csgjs_polygon> &list)
{
...
if (!front) front = new node(list_front);
if (!back) back= new node(list_back);
...
}
...
Рейтинг: 0 / 0
30.11.2016, 13:18
    #39357597
MasterZiv
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Почему не распараллеливаются потоки
Garfish,

я потом посмотрю всё, отпишусь...
сорри сейчас некогда...
...
Рейтинг: 0 / 0
30.11.2016, 13:20
    #39357602
MasterZiv
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Почему не распараллеливаются потоки
GarfishMasterZiv,

а применительно к конструктору node как это можно сделать?

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
void node::node(vector<csgjs_polygon> &list)
{
...
if (!front) front = new node(list_front);
if (!back) back= new node(list_back);
...
}



в очередной раз прошу посылать ВЕСЬ код...
сделать то можно, вопрос, что дальше будет.
...
Рейтинг: 0 / 0
30.11.2016, 13:53
    #39357641
д0k
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Почему не распараллеливаются потоки
GarfishDimitry Sibiryakov,

а как?



Сюда смотри,
Ищи как можно добраться до нужных тебе системных вызовов из используемой тобой
обертки.
...
Рейтинг: 0 / 0
30.11.2016, 22:59
    #39358090
MasterZiv
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Почему не распараллеливаются потоки
[quot Garfish]SashaMercury,

как в потоках реализовать разделяемое адресное пространство не знаю,

просто
0) выделить память
1) использовать только в этом потоке
2) вовремя удалить память

если использовать все виды стековой памяти , то вообще все автоматом разделяется.
...
Рейтинг: 0 / 0
Форумы / C++ [игнор отключен] [закрыт для гостей] / Почему не распараллеливаются потоки / 25 сообщений из 27, страница 1 из 2
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]