PDA

Показать полную графическую версию : [решено] Узнать количество ядер процессора


Anonymоus
10-07-2013, 21:00
Не так давно написал скрипт, скачивающий выбранный плейлист с YouTube, в своей работе он использует разделение задач пусть на примитивные, но всё же потоки, и распределяет оные по ядрам процессора. Хотелось бы его усовершенствовать и добавить автоматическое определение количества ядер (скрипт запускается на разных ПК с абсолютно неидентичным железом), но проблема в том, что я не знаю, как это реализовать. Подозреваю, что силами WMIC, но я не силён в нём. Надеюсь на помощь форумчан.
На всякий случай привожу сам скрипт:

@Echo Off
SetLocal EnableDelayedExpansion
:: YTDownloader v1.4
:: Anonymous, 2013. Ad majorem Applejack gloriam
:: Distributed under WTFPL license (http://www.wtfpl.net/)
:: Скрипт, скачивающий выбранный плейлист с ютуба в виде mp3
:: Работа с YouTube ведется через собственный API (тоже на батниках). Документация по API: http://ponyasha.tk/api/
:: Зависимости: wget (http://gnuwin32.sourceforge.net/packages/wget.htm) aria2 (http://aria2.sourceforge.net/)
:: Почему две утилиты для одной и той же цели? Aria не умеет писать данные в stdout, а wget скачивает в один поток
:: Да-да, реализована многопоточность и распределение процессов по ядрам. inb4: месье знает толк в извращениях


::==================================
:: Настройки
::==================================
:: Число потоков (обычно вполне хватает пяти)
Set Threads=5
:: Число используемых ядер процессора (не больше четырех)
Set Cores=4
:: Домен, на котором расположены используемые API
Set APIBaseURL=http://ponyasha.tk


::==================================
:: Обработчик параметров командной строки
::==================================
If "%~1"=="" Echo USAGE: %~nx0 ^<YouTube playlist ID^>&Exit /B
If "%~1"=="thread" GoTo Thread

::==================================
:: Работа с данными плейлиста
::==================================
:: Подготовка
If Not Exist audio MD audio
For /F "delims=" %%A In ('Dir "%Temp%\thread*.lock" /B 2^>nul') Do (Del "%Temp%\%%A")
If Exist "%Temp%\ytplaylist.txt" Del "%Temp%\ytplaylist.txt"
:: Получение ID видео
Set i=0
For /F "eol= delims=" %%A In ('wget "!APIBaseURL!/api/ytplist.bat?list=%~1" -q -O- 2^>nul') Do (
For %%B In (%%A) Do (
If "%%~B"=="Error:" Echo ERROR: Ivalid playlist ID or empty playlist&Exit /B
Echo %%~B>>"%Temp%\ytplaylist.txt"
Set /A i+=1
)
)

::==================================
:: Балансировка нагрузки
::==================================
:: Считаем количество заданий на поток
Set /A JobsPerThread=i/Threads
:: Проверяем на деление без остатка и распределяем диапазоны
Set /A Mod=JobsPerThread*Threads
For /L %%A In (1,1,!Threads!) Do (
Set /A Prev=%%A-1
Set /A Thread[%%A]min=Thread[!Prev!]max+1
Set /A Thread[%%A]max=JobsPerThread*%%A
)
:: Если поровну между потоками не делится, добавляем остаток к последнему
If Not "!Mod!"=="!i!" Set /A Thread[%Threads%]max=i-Mod+!Thread[%Threads%]max!
:: Если заданий меньше чем потоков, принудительно переводим в однопоточный режим
If !i! LSS !Threads! (
Set Thread[1]min=1
Set Thread[1]max=!i!
Set Threads=1
)
:: Распределяем потоки по ядрам (само собой, вместе с дочерними процессами)
If !Cores! GTR 4 Set Cores=4
Set Core=1&Set CoreID=1
For /L %%A In (1,1,!Threads!) Do (
Set Thread[%%A]core=!CoreID!
Call :AffinityMap
)
:: Вызываем потоки (копии самого себя, работающие в том же окне)
Echo YTDownload started
Echo INFO: !i! videos ready to processing
Echo v:0>"%Temp%\progress.data"
For /L %%A In (1,1,!Threads!) Do (
Start /B /affinity !Thread[%%A]core! %~nx0 thread !Thread[%%A]min!:!Thread[%%A]max! %%A !i!
)
:: Ожидание окончания всех потоков (интервал проверки - ~2 секунды)
:ThreadWatcher
Set AllDone=true
Ping -n 3 127.0.0.1>nul
For /L %%A In (1,1,!Threads!) Do (If Exist "%Temp%\thread%%A.lock" Set AllDone=false)
If "!AllDone!"=="false" GoTo ThreadWatcher
:: Завершение работы
Echo INFO: All threads finished
Del "%Temp%\ytplaylist.txt"
Exit /B

::==================================
:: Отдельный поток
::==================================
:Thread
:: Разбираем аргументы
Set ThreadNum=%~3
Set Videos=%~4
For /F "tokens=1,2 delims=:" %%A In ("%~2") Do (Set Min=%%A&Set Max=%%B)
:: Ставим локфайл
Echo.>"%Temp%\thread!ThreadNum!.lock"
:: Получаем только принадлежащие потоку данные
Set i=0
For /F "usebackq eol= delims=" %%A In ("%Temp%\ytplaylist.txt") Do (
Set /A i+=1
If !i! GEQ !Min! If !i! LEQ !Max! (
Set Err=0
For /F "eol= delims=" %%B In ('wget "!APIBaseURL!/api/yt2mp3.bat?v=%%A" -q -O- 2^>nul') Do (Set AudioURL=%%B)
:: Вывод сообщения о ошибке, генерируемого самим API
If "!AudioURL:~,6!"=="Error:" Echo ERROR: [%%A]!AudioURL:~6!&Set Err=1
If !Err!==0 (
:: Получение имени скачиваемого файла
For /F "eol= delims=" %%A In ("!AudioURL:/=\!") Do Set AudioName=%%~nxA
:: Сокращение отображаемых данных
Set DisplayedURL=!AudioURL!
If Not "!DisplayedURL!"=="!DisplayedURL:~-40!" Set DisplayedURL=!DisplayedURL:~,25!...!DisplayedURL:~-10!
If Not "!AudioName!"=="!AudioName:~-40!" Set AudioName=!AudioName:~,25!...!AudioName:~-10!
:: Инкрементация счетчика обработанных видео
For /F "usebackq tokens=2 delims=:" %%A In ("%Temp%\progress.data") Do (
Set /A Progress=%%A+1
Echo v:!Progress!>"%Temp%\progress.data"
Set /A Percentage=!Progress!*100/!Videos!
Title [!Progress!/!Videos!] !Percentage!%%
)
:: Многопоточное скачивание
Echo [!Progress!/!Videos!] !Percentage!%% Thread #!ThreadNum!: Downloading !DisplayedURL!
aria2c -j 10 -x 10 -s 10 --allow-overwrite=true -D -d "audio" "!AudioURL!">nul
Echo Thread #!ThreadNum!: Succesfuly downloaded: !AudioName!

)
)
)
:: Убираем локфайл и убиваем поток
Del "%Temp%\thread!ThreadNum!.lock"
Echo INFO: Thread !ThreadNum! finished
Exit

::==================================
:: Вспомогательные функции
::==================================
:AffinityMap
:: Получаем ID следующего ядра
If !Cores!==1 Set CoreID=1&Exit /B
Set /A CoreID="1<<Core"
Set /A Core+=1
If !Core!==!Cores! Set Core=0
Exit /B

Iska
10-07-2013, 21:25
Не забывайте про HT.
wmic.exe CPU get NumberOfCores, NumberOfLogicalProcessors
Может возвращать некорректный результат, потребны обновления: Win32_Processor NumberOfCores|NumberOfLogicalProcessors site:support.microsoft.com - Поиск в Google (https://www.google.ru/search?q=Win32_Processor+NumberOfCores%7CNumberOfLogicalProcessors+site%3Asupport.microsoft.com).

kiripanda
11-07-2013, 01:48
echo %NUMBER_OF_PROCESSORS%

LEmiD
20-12-2017, 06:26
Это количество ядер или потоков ?

Както на основе этого можно вычислить именно количество ядер ?
Я не знаю как именно у процей теперь, говорят i3 стали 4 ядерными.
В общем надо както узнать если ядер всего 2, то запустить на одном.
Предположим 4 потока, значит 2 ядра, запускаем в 2 потока чтоб работало на 1 ядре, забирать 2 это перебор.
Но если 4 ядра 4 потока, то желательно бы запустить на 2 ядрах или 3, вот в этом то и неувязка получается.
Проще наверно будет просто оставить 2 потока, а остальные занять

Iska
20-12-2017, 07:49
LEmiD, «И ты, Брут?». На своей машине можно и глазками посмотреть. А на чужой… Ну, зачем это Вам?!

alpap
20-12-2017, 14:46
LEmiD,
не каждый проц вы уговорите работать с ядрами по вашему желанию, что-то на ядро ОС скинет без вашего ведома и желания.

Iska
20-12-2017, 15:10
alpap, я так чую — это всё те же майнеры с запуском на чужих машинах, ОС тут не причём. Просто навскидку пробежитесь по последним двум десяткам сообщений коллеги LEmiD.

LEmiD
20-12-2017, 19:20
Как вы блин цвет выбираете, тут же нет палитры, ладно у меня в трее instant eyedropper завалялся и случайно открытая серая палитре потомучто впервые за месяци на одном форуме решил написать строчку палитрой, а тамашних цветов маловато, но они естьэто всё те же майнеры с запуском на чужих машинах
пробежитесь по последним двум десяткам сообщений коллеги

Любой кусок майнера палит любой антивирус. Кроме защитника, не хочет чтоб втискивали.
Вовсе не десяток, тем 5 максимум, и вообще в обучающих целях, пока интерес не пропал. Просто я криворук и ничё не доделываю когда результат известен.


Просто думал о интелах, а тут амд вспомнил, наверно ну их нахрен. Я даже не знаю у них тоже по 2 потока на ядро или им своих 16 ядер хватает?

Iska
20-12-2017, 19:53
и вообще в обучающих целях, пока интерес не пропал. »
Тогда, пожалуй, стоит ограничить достижение этих целей собственной машиной.

Как вы блин цвет выбираете, тут же нет палитры, »
https://i.imgur.com/SUAFy5n.png

alpap
21-12-2017, 01:21
тут же нет палитры »
Отчего же

["color=blue"]Этот текст синий["/color"]
(убрать кавычки для внедрения)

Iska
21-12-2017, 09:25
alpap, Вы процитировали не мои слова ;).

(убрать кавычки для внедрения) »
Для иллюстраций можно применять тэг noparse:
Этот текст будет синим
Этот текст будет синим
И этот тоже
И этот тоже

alpap
23-12-2017, 03:49
не мои слова »
да, извиняюсь, взял из вашего сообщения и соответственно ник ваш - не подумал
а как написать без преобразования, не знаю чем экранировать, не буду же здесь "играться", с кавычками более менее подучилось, так уже и оставил.




© OSzone.net 2001-2012