Visual Basic, .NET, ASP, VBScript
 

   
   
     

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

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

 

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

Автор вопроса:  Сергей Юдин
Я хочу купить двухядерный компьютер с процессором Intel Core I5 с частотой 3 ГГц вместо моего одноядерного компьютера с частотой 2 ГГц в надежде на то, что это позволит примерно на порядок увеличить производительность компьютера, т.к. сейчас мой компьютер решает мою задачу в программе Solsys7 целую неделю, а мне надо ее решать десятки раз (в лучшем случае) или сотни раз (в худшем случае). Конечно же, основной упор я делаю на наличие двух ядер, хотя и повышенная частота шины и памяти 1333 Мгц и повышенная оперативная память 2*4ГГб и наличие повышенной памяти кэша (даже трех уровней), тоже значительно повысят производительность компьютера.

Так вот вопрос состоит в том – можно ли в программе написанной на Visual Basic 6 запустить два потока (две нити) используя функцию API CreateThread для второго ядра. Исходя из документации Visual Basic 6 это возможно, но все мои попытки и отзывы других пользователей убеждают меня в том, что это только теоретическая возможность, а реально работает только один поток. Насколько я понимаю, это связано с тем, что виртуальная машина, т.е. библиотека msvbvm60.dll может работать только с одним потоком, хотя есть возможность установить семафор обращения к ней с помощью функции API CreateSemaphore, но это опять таки только в теории. По этому, я уточняя свой вопрос – можно ли реально в программе написанной на Visual Basic 6 запустить два потока (второй для другого процессора), если второй поток не обращается к библиотеке msvbvm60.dll, например, обращается к приложению Excell или к библиотеке DLL, написанной на другом языке, например, Free Basic. Можно, конечно же, без особых проблем применить технологию OpenMP, но ее поддерживает только VB.NET, а мне бы не хотелось 21 форму программы Solsys7 переделывать под NET (да и не нравится мне этот NET, т.к. в версии NET это уже не Visual Basic 6, а такой же язык, как и все остальные C++, Pascal и т.д.).

С наилучшими пожеланиями Сергей Юдин.

Ответить

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

Номер ответа: 1
Автор ответа:
 Smith



ICQ: adamis@list.ru 

Вопросов: 153
Ответов: 3632
 Профиль | | #1 Добавлено: 08.08.11 22:58
В VB6 нужно ужасно извратиться, чтобы написать что-то хотябы двух поточное. Но вроде бы есть примеры.
 
У меня только одна попытка из пяти увенчалась успехом. Как это получилось я сам непонял :-D

Удалось создать устойчивый поток для фоновой процедуры, отвязанный от основной нити программы.

Ответить

Номер ответа: 2
Автор ответа:
 Ким Чен Ир



Вопросов: 0
Ответов: 140
 Профиль | | #2 Добавлено: 08.08.11 23:36
Изврат с отладкой из-под IDE. Ну и дисциплина нужна.
библиотека msvbvm60.dll может работать только с одним потоком

Ничего подобного.
Пишем файл mytlb.idl с примерным содержимым:

  1. [dllname("ole32.dll")]
  2. module ole32
  3. {
  4.     [entry("OleInitialize")] long OleInitialize(long pvReserved);
  5. };
  6.  
  7. [dllname("kernel32.dll")]
  8. module kernel32
  9. {
  10.     [entry("CreateThread")] long CreateThread(long* lpsa, long dwSSz, long lpStAds, long lpParam, long Flags, long* lpThreadId);
  11.     [entry("Sleep")] void Sleep( long dwMilliseconds );
  12. };



Через командную строку студии делаем из него tlb:
midl /mktyplib203 /tlb D:\mytlb.tlb D:\mytlb.idl

Подключаем в рефренсах к проекту vb6.
Ну и собственно функция потока:
  1. Public Function thread_func(ByVal param As Long) As Long
  2. OleInitialize 0
  3. Dim i As Long
  4. For i = 0 To 100000
  5.     Form1.Label1.Caption = i
  6.     Sleep 100
  7. Next
  8. End Function



все api - задекларировать только в tlb

С отладкой мои соболезнования. :)

Ответить

Номер ответа: 3
Автор ответа:
 Smith



ICQ: adamis@list.ru 

Вопросов: 153
Ответов: 3632
 Профиль | | #3 Добавлено: 09.08.11 03:08
С отладкой я как-раз и зашился, бросил это дело.

Каддафи, звучит хорошо, а есть хоть один небольшой, но многопоточный проект в исходниках?
И всё-таки Как-же с сабжем? Муторно будет рулить потоки на ядра.
Или другой вопрос, аська, мыло есть?

Ответить

Номер ответа: 4
Автор ответа:
 Smith



ICQ: adamis@list.ru 

Вопросов: 153
Ответов: 3632
 Профиль | | #4 Добавлено: 09.08.11 14:55
моё adamis front ру, если есть пожалуйста кинь проект

Ответить

Номер ответа: 5
Автор ответа:
 Ким Чен Ир



Вопросов: 0
Ответов: 140
 Профиль | | #5 Добавлено: 09.08.11 20:19
Исходник скину, только почищу, а то там черт ногу сломит. Сам уже с трудом ориентируюсь.
Касательно сабжа: SetThreadAffinityMask

Ответить

Номер ответа: 6
Автор ответа:
 Smith



ICQ: adamis@list.ru 

Вопросов: 153
Ответов: 3632
 Профиль | | #6 Добавлено: 09.08.11 21:09
Каддафи М пишет:
Исходник скину

Меня интересует не только код, а проект целиком, файлы, наверняка самодельный cmd'шник или батник для компиляции :)
Мне интересно понять как вы подменой tlb оживляете обычные CreateThread.

Ответить

Номер ответа: 7
Автор ответа:
 Smith



ICQ: adamis@list.ru 

Вопросов: 153
Ответов: 3632
 Профиль | | #7 Добавлено: 10.08.11 13:15
  1. SetProcessAffinityMask(ByVal GetCurrentProcessId(), ByVal 1)

не работает, по идее должен быть выбран только второй проц, но маска не назначается

Ответить

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



Разработчик

Вопросов: 130
Ответов: 6602
 Профиль | | #8 Добавлено: 11.08.11 03:36
Core i5 вообще-то 4-ядерный
Ускорение ты в любом случае получишь. Даже одно ядро современного процессора на голову выше любого старого одноядерного процессора.

Ты правильно заметил что на .NET можно легко сделать многопоточность. Если не хочешь переписывать на него весь проект, можно на .NET сделать код вычислений и использовать из VB6 программы через COM, Named pipes и т.п.

Может даже есть смысл не на .NET это писать, а на С++

Ответить

Номер ответа: 9
Автор ответа:
 Ким Чен Ир



Вопросов: 0
Ответов: 140
 Профиль | | #9 Добавлено: 11.08.11 04:54
SetProcessAffinityMask(ByVal GetCurrentProcessId(), ByVal 1)
не работает, по идее должен быть выбран только второй проц, но маска не назначается


идентификатор процесса и его хендл в корне разные вещи.

Ответить

Номер ответа: 10
Автор ответа:
 Ким Чен Ир



Вопросов: 0
Ответов: 140
 Профиль | | #10 Добавлено: 11.08.11 05:01
P/s Smith. Проектик тебе отправил. Все не так сложно, как ты думаешь.
В новом потоке инициализируется ole и tls. И ограничить доступ к совместно используемым объектам.
Вообщем, разберешься.

Ответить

Номер ответа: 11
Автор ответа:
 Retupa



Вопросов: 1
Ответов: 51
 Профиль | | #11 Добавлено: 11.08.11 18:49
Каддафи М
Если не затруднит, залейте исходник (пусть даже вычещенный). Очень интересно посмотреть. Заранее спс.!

Ответить

Номер ответа: 12
Автор ответа:
 Ким Чен Ир



Вопросов: 0
Ответов: 140
 Профиль | | #12 Добавлено: 11.08.11 19:25
http://dump.ru/file/5344058

Ответить

Номер ответа: 13
Автор ответа:
 Smith



ICQ: adamis@list.ru 

Вопросов: 153
Ответов: 3632
 Профиль | | #13 Добавлено: 11.08.11 20:23
Каддафи М пишет:
идентификатор процесса и его хендл в корне разные вещи

Намек понял, попробую GetCurrentProcess

Ответить

Номер ответа: 14
Автор ответа:
 Smith



ICQ: adamis@list.ru 

Вопросов: 153
Ответов: 3632
 Профиль | | #14 Добавлено: 12.08.11 01:47
Пример посмотрел, изврат изящный :)
Выглядит готовым к употреблению, пока не переписал под своё не скажу, что заработало.
Передавать мелочевку безопасно из потока в поток можно и апишками, а крупняк можно временными файлами.

пошел выбор процессора

На форме пара листбоксов и пара кнопок
  1. Option Explicit
  2.  
  3. Private Declare Function GetProcessAffinityMask Lib "kernel32" (ByVal hProcess As Long, ByRef ProcessMask As Long, ByRef SystemMask As Long) As Long
  4. Private Declare Function SetProcessAffinityMask Lib "kernel32" (ByVal hProcess As Long, ByVal lMask As Long) As Long
  5. Private Declare Sub Sleep Lib "kernel32" (ByVal dwMilliseconds As Long)
  6.  
  7. Private Declare Function OpenProcess Lib "kernel32" (ByVal dwDesiredAccess As Long, ByVal bInheritHandle As Long, ByVal dwProcessId As Long) As Long
  8. Private Const PROCESS_ALL_ACCESS = &HF0000 Or &H100000 Or &HFFF      '2035711
  9.  
  10. Private Declare Function GetCurrentProcess Lib "kernel32" () As Long
  11. Private hCurrentProcess As Long
  12.  
  13.  
  14. Private Function Mask() As Long
  15.     Dim Item As Long
  16.  
  17.     For Item = 0 To List1.ListCount - 1
  18.         Mask = Mask + CLng(List2.Selected(Item)) * (2 ^ Item)
  19.     Next
  20.     If Mask = 0 Then List2.Selected(0) = True: Mask = 1 Else Mask = Abs(Mask)
  21.     Caption = Mask
  22.  
  23. End Function
  24.  
  25. Private Function ExtractBit(ByVal Dec As Byte, ByVal MyBit As Integer) As Boolean
  26.     ExtractBit = Dec And (2 ^ (MyBit - 1))
  27. End Function
  28.  
  29.  
  30. Private Function SetProcessMask(ByRef hProcess As Long, ByRef lMask As Long) As Boolean
  31.     Timer1.Enabled = False
  32.     SetProcessMask = SetProcessAffinityMask(hProcess, lMask) > 0
  33.     Sleep (0)
  34.     If SetProcessMask = True Then Caption = "Успешно!" Else Caption = "Ошибка!"
  35.     Timer1.Enabled = True
  36. End Function
  37.  
  38.  
  39. Private Sub Command1_Click() 'применить маску на себя
  40.     SetProcessMask hCurrentProcess, Mask
  41. End Sub
  42.  
  43. Private Sub Command2_Click() 'применить маску на новый инстанс программы
  44.     Dim Tmp As Long
  45.  
  46.     Tmp = CLng(Shell(App.Path & "\" & App.EXEName & ".exe", vbNormalFocus))
  47.     SetProcessMask OpenProcess(PROCESS_ALL_ACCESS, False, Tmp), Mask
  48. End Sub
  49.  
  50. Private Sub Form_Load()
  51.     For hCurrentProcess = 1 To CLng(Environ$("NUMBER_OF_PROCESSORS"))
  52.         List1.AddItem "Процессор #" & hCurrentProcess
  53.         List2.AddItem "Процессор #" & hCurrentProcess
  54.         List2.Selected(hCurrentProcess - 1) = True
  55.     Next
  56.     hCurrentProcess = GetCurrentProcess
  57. End Sub
  58.  
  59. Private Sub Timer1_Timer()
  60.     Dim ProcAffinityMask As Long, SysAffinityMask As Long
  61.     Dim Item As Long, Tmp As Byte
  62.  
  63.     GetProcessAffinityMask hCurrentProcess, ProcAffinityMask, SysAffinityMask
  64.  
  65.     For Item = 1 To List1.ListCount
  66.         List1.Selected(Item - 1) = ExtractBit(CByte(ProcAffinityMask), Item)
  67.     Next
  68.     Caption = vbNullString
  69. End Sub

Ответить

Номер ответа: 15
Автор ответа:
 Smith



ICQ: adamis@list.ru 

Вопросов: 153
Ответов: 3632
 Профиль | | #15 Добавлено: 12.08.11 03:14
Упаковал библиотечку UPX'ом, работает.
Еслиб вообще без неё, или хотябы саб мэйн без неё работал было бы лучше.
Ато никуда её нельзя деть, ни в тэмп ни тем более в подпапку.

Ответить

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

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



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