Форум программистов, компьютерный форум, киберфорум
Visual Basic .NET
Войти
Регистрация
Восстановить пароль
Карта форума Темы раздела Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.61/18: Рейтинг темы: голосов - 18, средняя оценка - 4.61
33 / 6 / 0
Регистрация: 12.01.2010
Сообщений: 85
1

Нагрузка на проц в циклах

09.04.2010, 11:30. Показов 3704. Ответов 12
Метки нет (Все метки)

Author24 — интернет-сервис помощи студентам
Всем привет. У меня самый простой вопрос, может кто знает. Почему циклы так грузят проц и как этого избежать? У меня 2 ядра и 1-ый под 100%. Вот пример:

VB.NET
1
2
3
4
5
6
Public Class Form1
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
        Do
        Loop
    End Sub
End Class
Вместо Do пытался вставить goto, както поэксперементировать, результат тотже. Самже я использую подобные циклы для проверок GetAsyncKeyState. Api функцию Sleep, чтобы делать задержки в этих циклах пытаюсь избегать, т.к. отрицательно влияет на работу в самих циклах. Вот как она выглядит:

VB.NET
1
Private Declare Sub Sleep Lib "kernel32" (ByVal dwMilliseconds As Integer)
Добавлено через 1 час 18 минут
И еще, почему только на одно ядро, когда у меня компиляция под любой процессор и у меня 2 ядра?
0
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
09.04.2010, 11:30
Ответы с готовыми решениями:

PING.EXE Нагрузка на проц
процеcc нагружает проц до 100% , ведёт cебя очень хитро и иногда cам отключает диcпетчер задач....

Тормоза системы, нагрузка на проц, хрипы звука
Доброго времени суток. Сталкиваюсь с такой проблемой уже не первый раз, но как то сейчас она меня...

После открытия диспетчера задач нагрузка на проц резко падает
Падает со 100% до нуля, антивирусы не помогли, переустановка винды тоже не помогла. Помогите...

При открытии диспетчера задач нагрузка на цп - 100%, после чего нагрузка падает
Всем привет.Начал фризить ноутбук.При открытии диспетчера задач ЦП загружен на 100%, но быстро...

12
4226 / 1795 / 211
Регистрация: 24.11.2009
Сообщений: 27,562
09.04.2010, 11:41 2
Цикл по определению последователен, а два и более ядер работают параллельно. Поэтому он не может исполняться на двух ядрах. Запусти два цикла в разных потоках - будут работать оба ядра. Или ищи опции неявного расщепления циклов - с ними будет использоваться не конкретно 2, а все ядра. Слып же усыпляет тот поток, в котором выполняется. Для распараллеливания это ничего не даст. Камень просто будет работать не всё время, но всё равно последовательно, то есть одним ядром в каждый момент времени, а в результате ты потратишь больше времени, но зато потоки других программ смогут получить больше квантов времени и выполниться быстрее. Слып следует ставить в тех потоках, которые делают работу большую, но капитально не срочную. Хочешь отсортировать гиганский массив, на это нужен час, но ты согласен ждать весь день? Тогда слыпом. Иначе слып тебе не нужен. Как вариант такой работы: анимашка с заданной скоростью: кадров надо показать много, но время тебе задано и если анимашка рассчитана на весь день, то тебе же самому не понравится, если она пролетит за час, но камень может быть способен показать кадры за час, тогда слып может быть полезен.
0
4337 / 1506 / 101
Регистрация: 12.04.2009
Сообщений: 2,342
09.04.2010, 11:52 3
Цитата Сообщение от taras atavin Посмотреть сообщение
Цикл по определению последователен
C#
1
2
3
4
    Parallel.For(0, 1000000, i =>
    {
        Console.WriteLine(i);
    });
Параллельный цикл
0
4226 / 1795 / 211
Регистрация: 24.11.2009
Сообщений: 27,562
09.04.2010, 12:09 4
Паралельный аналог, то есть то самое расщёпление цикла, только явное и не опцией, а оператором. Я писал про классический, а расширения могут определяться как угодно, лишь бы похоже. В том числе, можно отойти от последовательности. Вот только без специального указания комп об этом догадаться не способен. Ну для большей точности формулировок можно переписать начало: "Классические циклы for, while, do while по определению последовательны и не моугут". И предложение о расщеплении заменить на "Или ищи опции неявного расщепления или явные параллельные аналоги последовательных циклов - с ними будет использоваться не конкретно 2, а все ядра".
0
33 / 6 / 0
Регистрация: 12.01.2010
Сообщений: 85
09.04.2010, 14:05  [ТС] 5
О, чуваки, вы тут так круто объясняете, я ушёл кудато глубоко в мысли и чуть было там не застрял пасибо, интересно почитать. А есть ссылки на описание параллельных команд и работы с ними, какбы с примерами? Но обращу ваше внимание, был бы очень признателел за помощь в главной проблеме - почему цикл так грузит проц? Теоретически сам так думаю: эта шняжка гоняется по адресам с такой скоростью и таким количеством повторов, что проц начинает "раскаляться" немного смешно. Тогда как сделать простой бесконечный цикл без такой нагрузки? Может есть альтернативный вариант написанию кода? Щаз опишу чем тут занимаюсь:

Запускается форма с единственной клавишей старта. При нажатии сворачивается. Далее идёт анализ нажатия клавиши. Этот анализ при свёрнутом окне получается совершить только функцией api GetAsyncKeyState и производится он в бесконечном замкнутом цикле. После нажатия вызывается определенная процедура, являющаяся основой программы. Я также использую таймер и там тоже проверяю другие нажатия клавиши тойже функцией, являющиеся более важными, которые могут повлиять на ход выполнения основной процедуры (Про таймер, наверное зря сказал, наверное особо тут не играет роль, вас только запутал). Вот пример:

VB.NET
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
Imports System
Imports System.IO
Imports System.Globalization
Imports System.Drawing.Imaging 'для скриншота
Imports System.Windows.Forms
Imports System.Windows
Public Class Main
Private Declare Function GetAsyncKeyState% Lib "user32" (ByVal vKey As Long) ' для прверки нажатия клавиши
...
Private Sub Старт_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Старт.Click
Do
System.Windows.Forms.Application.DoEvents()
If GetAsyncKeyState(&H25) And GetAsyncKeyState(&H11) Then 'если нажата Left+Ctrl
... ' вызов процедуры
End If
Loop
End Sub
Private Sub Timer1_Tick(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Timer1.Tick
If GetAsyncKeyState(&H27) And GetAsyncKeyState(&H11) Then 'если нажата Right+Ctrl
  End ' закрытие программы
End If
End Sub
...
End Class
0
33 / 6 / 0
Регистрация: 12.01.2010
Сообщений: 85
10.04.2010, 15:11  [ТС] 6
знаете почему я всёже задался этим вопросом, может вспомните, кто писал когдато на старых языках программирования? Там подобные циклы были в порядке вещей и вообще никак не грузили проц. Как в бейсике, так и в ассемблере, паскале. Вот пример:
PureBasic
1
2
3
10 If [проверка клавиши] then goto 30 
20 goto 10 
30 ...
0
33 / 6 / 0
Регистрация: 12.01.2010
Сообщений: 85
14.04.2010, 09:07  [ТС] 7
Еще такой вопрос, вобщемто по теме, т.к. снова натыкаюсь на такой цикл. Что вы используете, если желаете паузу? Есть такая команда api sleep, она не катит, т.к. при её выполнении не работает Timer. Придумал такой вариант:
Создаю переменную boolean, отвечающую за активацию паузы и проворачиваю её в модуле Timer при проверки тек даты:
dtim - тек дата
dtplus - дата с прибавкой времени задержки
timact - true при активации таймера
timok - true - время пришло

VB.NET
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
If timact Then
            If timok = False Then
                Dim dtim As DateTime = DateTime.Now
                If dtplus <= dtim Then
                    timok = True
                    timact = False
                End If
            End If
        End If
 
А там где мне нужна пауза вставляю такую шмотку:
dtplus = DateTime.Now
dtplus = dtplus.AddSeconds(2) 'задержка
timact = True
            Do
                System.Windows.Forms.Application.DoEvents() ' нужно вставлять чтобы Timer не завис
            Loop Until timok
            timok = False
И теперь такаяже проблема нагрузки цпу при вечном цыкле в местах Do loop, вернее не вечном, но грузит полюбому.
0
4226 / 1795 / 211
Регистрация: 24.11.2009
Сообщений: 27,562
14.04.2010, 09:30 8
Цитата Сообщение от Spiritsun Посмотреть сообщение
цикл так грузит проц
А он и должен его грузить. Вопрос лишь, на долго ли. И даже параллельный цикл будет грузить, но уже два ядра сразу и на меньшее время. Слыпом можно эту нагрузку уменьшить, но увеличить время. И никогда не применяй слып в первиченом потоке.

Добавлено через 1 минуту
Цитата Сообщение от Spiritsun Посмотреть сообщение
Что вы используете, если желаете паузу
Там, где она нужна, - слып. Но все такие куски - только во вторичных потоках.

Добавлено через 9 минут
Цитата Сообщение от Spiritsun Посмотреть сообщение
не работает Timer
И не должен. Сама винда отслеживает, сколько поток должен дрыхнуть. sleep (100) - 100 миллисекунд, sleep (50) - 50 миллисекунд. Но винда имеет многозадачность не реального времени, а с разделением времени. Поэтому время паузы не гарантировано, задаётся только номинальная её продолжительность, точность же может не соответствовать разрешению. Например, вместо 50 реально вполне может оказаться и 60, а по различимости кодов между ними 11 позиций, ключая сами эти значения. И по-моему, для другого потока с номиналом задержки 60 может получиться задержка 50 миллисекунд. А гарантировать определённую длительность задержки под виндой нельзя. Я делал и так, как ты предлагаешь, но вместо номинальной частоты повторного исполнения 1000 Герц получил 15 Герц (задержка 67 миллесекунд), а если вообще без искуственных задержек, то 5000 Герц на той же машине и для той же задачи.

Добавлено через 2 минуты
Если тебя это не устраивает - ставь фотон (фотон - система реального времени, внешне похожая на винду, с теми же окнами, которые смогут перекрывать друг друга, сворачиваться, разворачиваться, динамически менять свои размеры, но при этом ещё прилады получают гарантированное быстродействие и гарантированную длительность задержек). Только я сомневаюсь, что ты сможешь легко писать для такой оси.
1
33 / 6 / 0
Регистрация: 12.01.2010
Сообщений: 85
14.04.2010, 13:37  [ТС] 9
Можно пример под vba2008 по организации потока, пжалста, пжалста, пжалста? Может комндами ManualResetEvent и AutoResetEvent надо делать, ток не въехал как.
0
4226 / 1795 / 211
Регистрация: 24.11.2009
Сообщений: 27,562
14.04.2010, 13:39 10
Эвент - событие, а поток - thread. Через него делай. Процедура старта потока валяется по-моему в оси и принимает адрес обычной процедуры, но в результате такого вызова указанная процедура становится точкой входа (функцией main) нового потока, при её завершении поток завершается, но процедура его старта возвращает управление не по завершении потока, а сразу. Хотя, на бейсике может и есть какой прибамбас для неявного вызова процедуры старта потока, но смысл должен сохраниться.
1
33 / 6 / 0
Регистрация: 12.01.2010
Сообщений: 85
14.04.2010, 13:42  [ТС] 11
Есть кусок программы? Может уже когдато делал? Прост выдрать бы и сюда
0
4226 / 1795 / 211
Регистрация: 24.11.2009
Сообщений: 27,562
14.04.2010, 13:51 12
Цитата Сообщение от Spiritsun Посмотреть сообщение
знаете почему я всёже задался этим вопросом, может вспомните, кто писал когдато на старых языках программирования? Там подобные циклы были в порядке вещей и вообще никак не грузили проц.
Разве? На старье всё грузило камень на 100%.

Добавлено через 3 минуты
И "вообще никак не грузить камень" невозможно. Любая работа, свалившаяся на комп хоть на долю процента, но грузит камень. Даже если надо переслать данные по DMA, запускает процесс именно камень, для этого он должен сам выполнить операцию, а это и есть нагрузка на камень, так как одновременно с этим он не моэжет выполнять в том же ядре ещё и другую работу. Тебе же надо перебрать значения переменной. Всю эту работу делает камень. + тебе ещё кажется надо опросить состояние клавиш. Для этого опять каждый раз нужен камень.
0
33 / 6 / 0
Регистрация: 12.01.2010
Сообщений: 85
14.04.2010, 17:42  [ТС] 13
мне всегото нужно написать самую простую программу, очень очень. Чтобы прерывалась только по нажатию клавиши или приостанавливалась (завершала процедуру) по нажатию другой. Притом какбы была в цикле, чтобы небыло выхода в форму, да я её вообще не использую, она в трей сворачивается. Сама прога выполняет в цикле сканирование экрана и анализирует. Вот и всё. И столько проблем. Прога готова и отлично работает, вот только с загрузкой проца под 100% не могу разобраться.

Добавлено через 1 час 37 минут
Ладно, кажись нашёл, всем кого еще заинтересует этот вопрос вот ссылки:
http://msdn.microsoft.com/ru-r... kz4s1.aspx
http://msdn.microsoft.com/ru-r... S.90).aspx

Добавлено через 1 час 58 минут
Поток - линейный, вся его прелесть лиж в паралельности. И когда я по закрытию потока поставил его открытие, какбы ввёл в цикл, то у меня была такаяже загрузка ядра на 100%. И еще проблема остается с паузой. Команда sleep, как говорите, приостанавливает поток. Тогда как в этот момент обработать нажатие клавиш "выход" и "отмена"?!

Может стоит поговорить о резидентных программах, которые в вечном цыкле крутятся в памяти? Как они делаются?
0
14.04.2010, 17:42
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
14.04.2010, 17:42
Помогаю со студенческими работами здесь

При открытии диспетчера задач нагрузка на ЦП 100%, через пару-тройку секунд нагрузка падает
При открытии диспетчера задач в Windows 10 пару-тройку секунд нагрузка на ЦП показывает 100%, а уже...

Ошибка в циклах
В примере есть 2 цикла(один в другом). Ссылка: http://ideone.com/lnxyf. Там получилось так, что...

Разобраться в циклах
Помогите, пожалуйста разобраться. Дана задача: &quot;Напишите программу, которая считывает с консоли...

рандомизация в циклах
У меня почему-то не работает рандомизация в циклах #include &lt;std_lib_facilities.h&gt; #include...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
13
Ответ Создать тему
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2024, CyberForum.ru