0 / 0 / 0
Регистрация: 25.04.2015
Сообщений: 26
|
||||||
1 | ||||||
Задача выполняется долго на одном ядре процессора - можно ли ее распараллелить25.04.2015, 02:21. Показов 2752. Ответов 42
Метки нет (Все метки)
Здравствуйте, коллеги!
Я с Delphi работаю давно, но монгопоточность не использовал. Сделал пока тупую переделку из однопоточной реализации алгоритма, для отработки собственно синтаксиса потоков... Об оптимизации пока речь не идет. Хоть как бы заработало без ошибок. Пока никак, вылетает с AccessViolation. Смысл в том, что во вложенных циклах перебираются все комбинации 4-х численных переменных. Происходят некие вычисления, в основном чтение из большого массива глобальной переменной, анализ данных и выдача результатов в другой массив глобальной переменной, вывод некоторых данных в окошко формы. Задача выполняется долго, на одном ядре процессора. Хочется распараллелить. Что я делаю не так? Код ниже.
0
|
25.04.2015, 02:21 | |
Ответы с готовыми решениями:
42
Запуск 22-х ядерного процессора на одном ядре Повышенное напряжение на ядре процессора Рекурсивный метод проверки файлов на изменения на одном четвёртом ядре На одном ядре 90-100% во время простоя (Intel core i3 2100) |
пофигист широкого профиля
4733 / 3167 / 859
Регистрация: 15.07.2013
Сообщений: 18,252
|
|
25.04.2015, 02:27 | 2 |
И до сих пор не научился форматировать код?
Твою простыню читать - врагу не пожелаешь. А в ней ещё и купюры есть. Ты специально постарался сделать максимум того, чтобы тебе никто не ответил/не помог?
0
|
0 / 0 / 0
Регистрация: 25.04.2015
Сообщений: 26
|
||||||
25.04.2015, 02:31 [ТС] | 3 | |||||
Попытка номер два. )
0
|
пофигист широкого профиля
4733 / 3167 / 859
Регистрация: 15.07.2013
Сообщений: 18,252
|
|
25.04.2015, 02:43 | 4 |
С форматированием уже лучше стало.
Но AccessViolation это такая штука, причину которой весьма трудно найти даже в "форматированной простыне". Уж извини. Если можешь сказать после каких действий в программе получаешь AV, то может что-то смогу подсказать. Если нет, то только поможет прикладывание к сообщению проекта в целом.
0
|
0 / 0 / 0
Регистрация: 25.04.2015
Сообщений: 26
|
||||||
28.04.2015, 17:09 [ТС] | 6 | |||||
Извиняюсь, что долго не отвечал. Наконец дошли руки до этой программы.
Путем экспериментов выяснилось, что сбой вызывает попытка копирования массива, тип которого задается в основном модуле (BarType). Что же с этим делать?
Дальнейшие эксперименты показали, что проблема в том, что массив Array[1..1000000] of Word; - слишком большой для нити. вот такой уже работает: Array[1..100000] of Word; Добавлено через 6 минут Ok. Значит этот массив не копируем, будем обращаться из ThreadFunc к внешнему. Добавлено через 4 минуты У меня к вам вопрос. Вообще имеет ли смысл копировать глобальные переменные в локальные для нити, если доступ к ним из нити предполагается только на чтение. И нужно ли при чтении глобальных переменных внутри нити, делать это в критических секциях? Добавлено через 1 час 3 минуты Еще такой вопрос. Если один поток будет писать в глобальную переменную в критической секции, и в это же время другой поток затребует чтение из этой переменной (без критической секции - чтение же), что будет?
0
|
2664 / 2270 / 279
Регистрация: 24.12.2010
Сообщений: 13,723
|
|
28.04.2015, 20:53 | 7 |
Бардак будет, если операция чтения/записи не атомарная)
Глобальные переменные вообще не имеют смысла, если без них можно обойтись и нужно обходиться
0
|
0 / 0 / 0
Регистрация: 25.04.2015
Сообщений: 26
|
||||||
28.04.2015, 21:20 [ТС] | 8 | |||||
Как сделать, чтобы было атомарно?
Можно бы было, обошелся бы. ) Например счетчик числа нитей. Время от времени выбивало ошибку IntegerOweflov на его декременте в нити:
Сделал инкремент в основном потоке еще до запуска нити. И поместил его там тоже в критическую секцию. На сколько это правильно?...
0
|
2664 / 2270 / 279
Регистрация: 24.12.2010
Сообщений: 13,723
|
|
28.04.2015, 21:29 | 9 |
Атрмарными можно считать только операции с данными размером в 1 байт.
Ну а с чего ты взял что виновата в этом не иначе как кривая работа с крит.секциями ?) И причем здесь глобальность переменной ? Те же грабли ждут при любой ее области видимости) Вот и обходись, никто же не запрещает)
0
|
0 / 0 / 0
Регистрация: 25.04.2015
Сообщений: 26
|
|
28.04.2015, 21:47 [ТС] | 10 |
Тогда почему возникают проблемы со счетчиком нитей, если это байтовая переменная?
MaxNumThreads, FThreadRefCount : Byte; Увеличение происходит до запуска нити. Уменьшение - перед уничтожением.
0
|
2664 / 2270 / 279
Регистрация: 24.12.2010
Сообщений: 13,723
|
|
28.04.2015, 21:50 | 11 |
Это какая байтовая ? FThreadRefCount что ли ?
Ну и где же она байтовая, если она объявлена как Word ?
0
|
0 / 0 / 0
Регистрация: 25.04.2015
Сообщений: 26
|
|
28.04.2015, 21:52 [ТС] | 12 |
Это было в 1й версии. Теперь байт.
Пока обошел эту ошибку, сделав счетчик Integer. И без крит. секций инкремент/декремент вот этими операторами: InterlockedDecrement(FThreadRefCount); InterlockedIncrement(FThreadRefCount);
0
|
2664 / 2270 / 279
Регистрация: 24.12.2010
Сообщений: 13,723
|
|
28.04.2015, 21:59 | 13 |
0
|
0 / 0 / 0
Регистрация: 25.04.2015
Сообщений: 26
|
|
28.04.2015, 22:09 [ТС] | 14 |
Тебе на психологический форум надо, а не на програмистский. Такие ответы в стиле "ну ты и дебил" исходят обычно от людей с большими проблемами... зажатое эго прет, найдя микроскопическое якобы превосходство над кем-то в чем-то. )))
0
|
28.04.2015, 22:09 | 15 |
и самое главное нужно написать еще, а что должно происходить-то
это апофеоз использования потоков все что делалось раньше, делалось, чтобы этого не было! может, все-таки объяснишь, что конкретно должно происходить, а тебе смогут рассказать не как запускать потоки, а как надо сделать, чтобы решить задачу
1
|
2664 / 2270 / 279
Регистрация: 24.12.2010
Сообщений: 13,723
|
|
28.04.2015, 22:13 | 16 |
BittenByCat,
Не по теме: а что это ты так раздухарился ? Я всего лишь стремлюсь заставить тебя думать, рассуждая вслух .. Истина-то рождается в движении мысли)
0
|
0 / 0 / 0
Регистрация: 25.04.2015
Сообщений: 26
|
|
28.04.2015, 22:20 [ТС] | 17 |
В основном модуле происходит перебор четырех параметров в заданных диапазонах.
Для каждого набора этих четырех параметров нужно произвести расчеты. Кстати передачу этих параметров в потоки я уже реализовал через 4-й параметр функции BeginThread - Param : Pointer; Расчеты проводятся в еще одном цикле. Результаты должны записаться в результирующий массив. Массивы входных данных достаточно большие - под Гигабайт. Программа относительно заработала. Но время от времени происходит IntegerOwerflov на декременте счетчика нитей. И еще она иногда просто повисает. Похоже потоки входят в бесконечный цикл. Добавлено через 3 минуты Кстати, а как это место правильно сделать? Нужно, что бы для каждой итерации основного цикла, перебирающего 4 параметра, запустилась нить, которая проведет расчеты для этой комбинации. И при этом число нитей не превысило максимально заданное. И чтобы окошко формы не залипало. )
0
|
2664 / 2270 / 279
Регистрация: 24.12.2010
Сообщений: 13,723
|
|
28.04.2015, 22:20 | 18 |
0
|
0 / 0 / 0
Регистрация: 25.04.2015
Сообщений: 26
|
|
28.04.2015, 22:25 [ТС] | 19 |
BeginThread - это системная функция, запускающая процедуру или функцию нити.
А нить у меня в процедуре. ThreadFunc.
0
|
2664 / 2270 / 279
Регистрация: 24.12.2010
Сообщений: 13,723
|
|
28.04.2015, 22:31 | 20 |
Начинать нужно совсем с другого места - с полной ликвидации в теле поточной функции любых обращений к глобальным переменным, к формам, к компонентам на этих формах.
Поточная ф-ция, прежде всего, должна быть независима и самодостаточна - получила вх.параметр[ы], произвела необходимые вычисления, вернула/выгрузила их результат[ы], как и положено ф-ции или процедуре, либо через Result либо черех вх.параметры, переданные по ссылке Добавлено через 1 минуту И опять нет логики) Нить у тебя в процедуре, а обозвал ты ее таки ThreadFunc.. Добавлено через 2 минуты Вот это тоже сомнительный и рискованый финт. Он тебе вообще зачем ?
0
|
28.04.2015, 22:31 | |
28.04.2015, 22:31 | |
Помогаю со студенческими работами здесь
20
Назначить каждому потоку на каком ядре процессора работать Код не выполняется в одном месте, но выполняется в другом Распараллелить выполнение цикла на все ядра процессора Как настроить Планировщик задач так, чтобы один процесс работал полностью на одном ядре? Программа долго выполняется Долго выполняется запрос Искать еще темы с ответами Или воспользуйтесь поиском по форуму: |