Visual Basic, .NET, ASP, VBScript
 

   
   
     

Форум - Общий форум

Страница: 1 | 2 | 3 | 4 | 5 |

 

  Вопрос: Два ядра под VB6 Добавлено: 08.08.11 21:43  

Автор вопроса:  Сергей Юдин

Ответить

  Ответы Всего ответов: 69  

Номер ответа: 31
Автор ответа:
 Сергей Юдин



Вопросов: 8
Ответов: 81
 Профиль | | #31 Добавлено: 13.08.11 21:47
Следующий наводящий вопрос, как потоку в dll после обработки неких данных вернуть результат вычислений в основной поток(тот который в exe)?


Раньше я делал в одном потоке это через передаваемые в DLL переменные

Private Declare Function XYZ Lib "spuskDLL.dll" Alias "XYZ@12" (ByVal kodDLL _
As Integer, ByVal i As Integer, ByRef param As Double) As Double


А из DLL забирал данные по задаваемым в основной программе kodDLL и i

function XYZ alias "XYZ" (byval kodDLL as integer, byval i as integer, _
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
Можно, только придется в цикле (или через wait-функцию) в основном потоке ждать, когда-же function XYZ в другом потоке обработает наконец данные.


А здесь я уже придумал, что делать. У меня первый поток работает в несколько раз быстрее второго, следовательно, ждать должен только он. После того, как второй поток получит на очередном шаге новые данные, он останавливается (переменные будут 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
как назначить потоку "реалтайм"

Зачем потоку, если можно всему своему процессу?
Например вот так
  1. Option Explicit
  2.  
  3. Private Declare Function SetPriorityClass Lib "kernel32" (ByVal hProcess As Long, ByVal dwPriorityClass As Long) As Long
  4. Private Declare Function GetCurrentProcess Lib "kernel32" () As Long
  5.  
  6. Private Const REALTIME_PRIORITY_CLASS = &H100
  7. Private Const HIGH_PRIORITY_CLASS = &H80
  8. Private Const NORMAL_PRIORITY_CLASS = &H20
  9. Private Const IDLE_PRIORITY_CLASS = &H40
  10.  
  11. Public Sub GetRealTimePrioritet()
  12.     Dim Handle As Long
  13.  
  14.     Handle = GetCurrentProcess
  15.     Call SetPriorityClass(Handle, &H100)
  16. End Sub
, а потоку помоему при создании приоритет выставляется

Ответить

Номер ответа: 43
Автор ответа:
 Artyom



Разработчик

Вопросов: 130
Ответов: 6602
 Профиль | | #43 Добавлено: 14.08.11 03:44
Сергей Юдин пишет:
если второй поток будет запущен на втором ядре (только как сделать, чтобы он не запустился на первом ядре).


Сергей, я повторюсь, нельзя писать многопоточное приложение, даже не понимая что такое многопоточность.

На каком ядре какой поток запускать - это задача которую решает планировщик. Причем он не будет четко разделять - один поток на одном ядре, другой на другом, а будет условно случайным образам выдавать им кванты времени, Т.е. в среднем поток половину времени проработает на первом ядре, половину на втором. То же самое если потоков будет 10.
Ты можешь ограничить набор ядер, на котором должен выполняться процес (AffinityMask). Как я гооврил, в этом почти никогда не возникнет необходимости, потому что планировщик и так всю работу за тебя сделает.

Ответить

Номер ответа: 44
Автор ответа:
 Artyom



Разработчик

Вопросов: 130
Ответов: 6602
 Профиль | | #44 Добавлено: 14.08.11 03:53
Smith пишет:
Если два потока будут активно синхронизироваться допустим записывая данные в одну переменную, и при этом потоки будут разнесены на разные ядра, то в результате скорее всего получим дикие тормоза, а не ускорение.

Замедление ты получишь не из-за этого, а из-за того, что механизмы синхронизации режима ядра относительно медленные. Если для синхронизации нужны частые короткие эксклюзивные блокировки (а для модификации переменной они имено такими и будут) можно использовать механизмы синхронизации режима пользователя.
Они работают намного быстрее, но при этом не могут приостановит поток (во время блокировки он находится в режиме spin wait, т.е. продолжает грузить процессор - поэтому их следует использовать только для коротких блокировок), и не могут работать между процессами.

Ответить

Номер ответа: 45
Автор ответа:
 Artyom



Разработчик

Вопросов: 130
Ответов: 6602
 Профиль | | #45 Добавлено: 14.08.11 03:57
Ну вот теперь и до реалтайма добрались

Ответить

Страница: 1 | 2 | 3 | 4 | 5 |

Поиск по форуму



© Copyright 2002-2011 VBNet.RU | Пишите нам