Страница: 1 | 2 | 3 | 4 | 5 |
Вопрос: Два ядра под VB6
Добавлено: 08.08.11 21:43
Автор вопроса: Сергей Юдин
Ответы
Всего ответов: 69
Номер ответа: 31
Автор ответа:
Сергей Юдин
Вопросов: 8
Ответов: 81
Профиль | | #31
Добавлено: 13.08.11 21:47
Раньше я делал в одном потоке это через передаваемые в DLL переменные
As Integer, ByVal i As Integer, ByRef param As Double) As Double
А из DLL забирал данные по задаваемым в основной программе kodDLL и i
byref param as double) as double export' функция библиотеки написана на FreeBasic
.....................................
Select Case kodDLL
Case 11:function =X(i)
Case 12:function =Y(i)
Case 13:function =VX(i)
Case 14:function =VY(i)
Case 15:function =FX(i)
Case 16:function =FY(i)
Case 17:function =kx(i)
Case 18:function =ky(i)
Case 19:function =Tmax(i)
Case 20:function =prock(i)
End Select
End Function
Но сейчас хочу попробовать забирать данные через массив данных param, которые передаются в DLL по ссылке.
С наилучшими пожеланиями Сергей Юдин.
Номер ответа: 32
Автор ответа:
Ким Чен Ир
Вопросов: 0
Ответов: 140
Профиль | | #32
Добавлено: 13.08.11 22:16
Можно, только придется в цикле (или через wait-функцию) в основном потоке ждать, когда-же function XYZ в другом потоке обработает наконец данные.
Номер ответа: 33
Автор ответа:
Smith
ICQ: adamis@list.ru
Вопросов: 153
Ответов: 3632
Профиль | | #33
Добавлено: 13.08.11 22:25
Об этоя и я спрашивал.
Каддафи объяснил, что для этого нужно использовать SetThreadAffinityMask.
Я убедился, что это работает.
Беда в другом.
Если два потока будут активно синхронизироваться допустим записывая данные в одну переменную, и при этом потоки будут разнесены на разные ядра, то в результате скорее всего получим дикие тормоза, а не ускорение.
Номер ответа: 34
Автор ответа:
Ким Чен Ир
Вопросов: 0
Ответов: 140
Профиль | | #34
Добавлено: 13.08.11 22:41
Пробелы в образовании не позволяют мне убогому подобрать пример, где бы требовалось ручное управление ядрами. Может быть в каких-то системах реального времени, навороченных игрушках, а? Но не виндоус, и не с бейсиком.
Номер ответа: 35
Автор ответа:
Сергей Юдин
Вопросов: 8
Ответов: 81
Профиль | | #35
Добавлено: 13.08.11 23:00
Если два потока будут активно синхронизироваться допустим записывая данные в одну переменную, и при этом потоки будут разнесены на разные ядра, то в результате скорее всего получим дикие тормоза, а не ускорение.
У меня этого не должно получиться, т.к. в начале работы основная программа задаст массив переменных, а затем будет только читать эти данные, которые будут изменяться и записываться во втором потоке, т.е. в DLL. И потом синхронизировать (притормаживать) свою работу будет только первый поток, т.к. по времени выполнения критичным является второй, где решаются дифференциальные уравнения.
С наилучшими пожеланиями Сергей Юдин.
Номер ответа: 36
Автор ответа:
Сергей Юдин
Вопросов: 8
Ответов: 81
Профиль | | #36
Добавлено: 13.08.11 23:08
Не понял, что это означает. Что под виндос второй поток из бэйсика обязательно запустится на втором ядре или, как Вы писали для этого надо использовать SetThreadAffinityMask.
С наилучшими пожеланиями Сергей Юдин.
Номер ответа: 37
Автор ответа:
Ким Чен Ир
Вопросов: 0
Ответов: 140
Профиль | | #37
Добавлено: 13.08.11 23:27
Этим я хотел сказать, что каким-бы ядром не овладел поток, его вытеснит другим потоком операционная система Windows.
Любой поток запуститься на том ядре, которою сочтет нужным использовать планировщик Windows, если не указать явно через SetThreadAffinityMask, SetThreadIdealProcessor.
Все ядра имеют одинаковую скорость работы, вопрос тогда стоит так, как долго разрешит система конкретному потоку занимать процессорное время. Может быть лучше назначить потоку приоритет через SetThreadPriority.
Попробуй поэкпериментировать, однозначного ответа нет. Может здесь начинается искусство?
Номер ответа: 38
Автор ответа:
Smith
ICQ: adamis@list.ru
Вопросов: 153
Ответов: 3632
Профиль | | #38
Добавлено: 13.08.11 23:45
Где-то на просторах MSDN я читал, что в случаях с ГиперТрэдингом первая половина процессоров в маске это реальные, а вторая половина виртуальные процессора.
Следовательно, для получения максимума скорости вычислений например с плавающей точкой, нужно назначить "реалтайм" приоритет потоку и послать его работать на реальном ядре, а не виртуальном.
Ссылку лучше гугл покажет, непомню.
Номер ответа: 39
Автор ответа:
Сергей Юдин
Вопросов: 8
Ответов: 81
Профиль | | #39
Добавлено: 14.08.11 00:05
А как назначить потоку "реалтайм". Первый раз с этим сталкиваюсь.
С наилучшими пожеланиями Сергей Юдин.
Номер ответа: 40
Автор ответа:
Сергей Юдин
Вопросов: 8
Ответов: 81
Профиль | | #40
Добавлено: 14.08.11 00:16
А здесь я уже придумал, что делать. У меня первый поток работает в несколько раз быстрее второго, следовательно, ждать должен только он. После того, как второй поток получит на очередном шаге новые данные, он останавливается (переменные будут ststic) после отправки SendMessage в одно из окошек первого потока. Первый поток тут же обращается к DLL и передает ей новое значение смоделированного времени и считывает при этом полученные данные, которые начинает обрабатывать. А т.к. времени это займет меньше, чем у второго потока на получение новых данных, то после обработки данных он просто останавливается и стоит до получения нового SendMessage от второго потока.
С наилучшими пожеланиями Сергей Юдин.
Номер ответа: 41
Автор ответа:
Ким Чен Ир
Вопросов: 0
Ответов: 140
Профиль | | #41
Добавлено: 14.08.11 01:14
Да, это имеет право на существование.
Можно еще, (чтоб не сабклассить окошки) послать PostThreadMessage, и ловить его в отдельно организованном GetMessage.
Но это на любителя.
Удачи.
Номер ответа: 42
Автор ответа:
Smith
ICQ: adamis@list.ru
Вопросов: 153
Ответов: 3632
Профиль | | #42
Добавлено: 14.08.11 02:49
Зачем потоку, если можно всему своему процессу?
Например вот так
Номер ответа: 43
Автор ответа:
Artyom
Разработчик
Вопросов: 130
Ответов: 6602
Профиль | | #43
Добавлено: 14.08.11 03:44
если второй поток будет запущен на втором ядре (только как сделать, чтобы он не запустился на первом ядре).
Сергей, я повторюсь, нельзя писать многопоточное приложение, даже не понимая что такое многопоточность.
На каком ядре какой поток запускать - это задача которую решает планировщик. Причем он не будет четко разделять - один поток на одном ядре, другой на другом, а будет условно случайным образам выдавать им кванты времени, Т.е. в среднем поток половину времени проработает на первом ядре, половину на втором. То же самое если потоков будет 10.
Ты можешь ограничить набор ядер, на котором должен выполняться процес (AffinityMask). Как я гооврил, в этом почти никогда не возникнет необходимости, потому что планировщик и так всю работу за тебя сделает.
Номер ответа: 44
Автор ответа:
Artyom
Разработчик
Вопросов: 130
Ответов: 6602
Профиль | | #44
Добавлено: 14.08.11 03:53
Если два потока будут активно синхронизироваться допустим записывая данные в одну переменную, и при этом потоки будут разнесены на разные ядра, то в результате скорее всего получим дикие тормоза, а не ускорение.
Замедление ты получишь не из-за этого, а из-за того, что механизмы синхронизации режима ядра относительно медленные. Если для синхронизации нужны частые короткие эксклюзивные блокировки (а для модификации переменной они имено такими и будут) можно использовать механизмы синхронизации режима пользователя.
Они работают намного быстрее, но при этом не могут приостановит поток (во время блокировки он находится в режиме spin wait, т.е. продолжает грузить процессор - поэтому их следует использовать только для коротких блокировок), и не могут работать между процессами.
Номер ответа: 45
Автор ответа:
Artyom
Разработчик
Вопросов: 130
Ответов: 6602
Профиль | | #45
Добавлено: 14.08.11 03:57
Ну вот теперь и до реалтайма добрались