Компьютерный форум OSzone.net  

Компьютерный форум OSzone.net (http://forum.oszone.net/index.php)
-   Скриптовые языки администрирования Windows (http://forum.oszone.net/forumdisplay.php?f=102)
-   -   [решено] Узнать количество ядер процессора (http://forum.oszone.net/showthread.php?t=264111)

Anonymоus 10-07-2013 21:00 2182761

Узнать количество ядер процессора
 
Не так давно написал скрипт, скачивающий выбранный плейлист с 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 2182773

Не забывайте про HT.
Код:

wmic.exe CPU get NumberOfCores, NumberOfLogicalProcessors
Может возвращать некорректный результат, потребны обновления: Win32_Processor NumberOfCores|NumberOfLogicalProcessors site:support.microsoft.com - Поиск в Google.

kiripanda 11-07-2013 01:48 2182864

echo %NUMBER_OF_PROCESSORS%

LEmiD 20-12-2017 06:26 2785725

Это количество ядер или потоков ?

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

Iska 20-12-2017 07:49 2785730

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

alpap 20-12-2017 14:46 2785798

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

Iska 20-12-2017 15:10 2785805

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

LEmiD 20-12-2017 19:20 2785888

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


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


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

Iska 20-12-2017 19:53 2785897

Цитата:

Цитата LEmiD
и вообще в обучающих целях, пока интерес не пропал. »

Тогда, пожалуй, стоит ограничить достижение этих целей собственной машиной.

Цитата:

Цитата LEmiD
Как вы блин цвет выбираете, тут же нет палитры, »

Вот так

alpap 21-12-2017 01:21 2785963

Цитата:

Цитата Iska
тут же нет палитры »

Отчего же

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

Iska 21-12-2017 09:25 2785991

alpap, Вы процитировали не мои слова ;).

Цитата:

Цитата alpap
(убрать кавычки для внедрения) »

Для иллюстраций можно применять тэг noparse:
Скрытый текст
Код:

[color=blue]Этот текст будет синим[/color]
Этот текст будет синим
Код:

[color=#0000FF]И этот тоже[/color]
И этот тоже


alpap 23-12-2017 03:49 2786324

Цитата:

Цитата Iska
не мои слова »

да, извиняюсь, взял из вашего сообщения и соответственно ник ваш - не подумал
а как написать без преобразования, не знаю чем экранировать, не буду же здесь "играться", с кавычками более менее подучилось, так уже и оставил.


Время: 03:25.

Время: 03:25.
© OSzone.net 2001-