Имя: Пароль:
IT
 
Как получить частоту процессора
,
0 H A D G E H O G s
 
22.11.21
21:35
День добрый.
Нужно определить частоту процессора, мгновенную.
Я пробовал и через RdTSC, вида

function RdTSC0: TTicks64;
asm
  {$IFDEF CPUX64}
  xor   rax, rax
  push  rbx          // Delphi requires EBX/RBX to be preserved
  cpuid              // full fence
  pop   rbx
  rdtsc
  shl   rdx, 32
  or    rax, rdx
  {$ELSE}
  xor   eax, eax
  push  ebx
  cpuid
  pop   ebx
  rdtsc
  {$ENDIF}
end;

и через CallNtPowerInformation(InformationLevel: Byte; lpInputBuffer: Pointer; nInputBufferSize: Longint; lpOutputBuffer: Pointer; nOutputBufferSize: Longint): Byte; stdcall; external 'PowrProf.dll';

оба варианта возвращают мне базовую частоту, даже когда ядро под нагрузкой. И даже на многих других серверах такая же картина (вдруг у меня локально что-то не так).
Кто - нибудь сталкивался?
1 H A D G E H O G s
 
22.11.21
21:37
Вот пример на дельфе для WinAPI

function CallNtPowerInformation(InformationLevel: Byte; lpInputBuffer: Pointer; nInputBufferSize: Longint; lpOutputBuffer: Pointer; nOutputBufferSize: Longint): Byte; stdcall; external 'PowrProf.dll';
type
  TPINFO = record
    Number: UINT;
    MaxMh: UINT;
    CurrentMhz: UINT;
    MhzLimit: UINT;
    MaxIdleState: UINT;
    CurrentIdleState: UINT;
  end;

  Function DummyThread(Param:pointer):Cardinal;stdcall;
  var x:integer; y:real;
  begin
    x:=0;
    while true do begin
    y:=cos(x);
    inc(x);
    if x>100000 then x:=0;
    end;
  end;

procedure TForm1.Button1Click(Sender: TObject);
var
  SI:_SYSTEM_INFO;
  NumberOfProcessors:Cardinal;
  PINFO: Array of TPINFO;
  res: Byte;
  resBool:Boolean;
  PID:Cardinal;
  ProcessAffinityMask: Cardinal;
  hProcess,hThread:THandle;
begin
  hProcess:=GetCurrentProcess();
  ProcessAffinityMask:=0;
  ProcessAffinityMask:=ProcessAffinityMask or (1 shl 1);
  resBool:=SetProcessAffinityMask(hProcess,ProcessAffinityMask);
  if resBool=false then begin
    ShowMessage(_GetErrorMsg(GetLastError));
    exit;
  end;
  GetSystemInfo(SI);
  NumberOfProcessors:=SI.dwNumberOfProcessors;
  hThread:=CreateThread(nil,0,@DummyThread,nil,0,PID);
  sleep(3000);
  SetLength(PINFO, NumberOfProcessors);
  ZeroMemory(@PINFO[0], sizeOf(TPINFO) * NumberOfProcessors);
  res := CallNtPowerInformation(11, nil, 0, @PINFO[0], sizeOf(TPINFO) * NumberOfProcessors);
  ShowMessage('CurrentMhz:'+inttostr(PINFO[0].CurrentMhz)+'//MaxMh:'+inttostr(PINFO[0].MaxMh));
  TerminateThread(hThread,0);
end;

Кидаю приложение на 2 ядро, на нем же запускаю поток, для него же вывожу текущую и максимальную частоту.
Получаю:
https://prnt.sc/20j1axs
На серваке тоже самое:
https://prnt.sc/20j1kbd

Аналогично все через RdTSC
2 vde69
 
22.11.21
21:40
для начала попутные вопросы
1. какой проц
2. другие железки и софт

вообще на сколько я понимаю ядра умеют сами себя ограничивать по частоте, то есть реальная работа ядра 1 может отличатся от частоты ядра 2,

или тебя интересует частота конвейера команд? так это надо смотреть частоту кеша L2/L1

зы
думаю на данном форуме тебе вряд-ли кто поможет...
3 H A D G E H O G s
 
22.11.21
21:42
Процы i5-8600k и Xeon-E2288G
Максимальная производительность, подтверждается сравнением с референсными показателями в CPU-Z
4 МихаилМ
 
22.11.21
21:51
(0) wmi уведомления  появилась в windows 2000 . 20 лет назад .
5 H A D G E H O G s
 
22.11.21
21:53
(4) wmi уведомления - это зависимость от запущенной службы.
6 H A D G E H O G s
 
22.11.21
21:54
(4) Но если не получится другим путем - пойдем через wmi
7 acht
 
22.11.21
22:13
(0) Посмотри как это сделано, например в https://github.com/anrieff/libcpuid  - где-нибудь в потрохах cpu_clock_by_ic(). Потом покрестись левой пяткой и заиспользуй всю бибилиотеку целиком =)
8 H A D G E H O G s
 
22.11.21
22:34
(7) Шептать там динозавр. Они там тащать частоту из реестра венды, и если не получилось, запускают свою йобу. Изучать я это конечно буду, но на свежую голову.
9 Злопчинский
 
22.11.21
22:47
(8) а ты думал только в 1С костыли и велосипеды? ;-)
10 Garykom
 
гуру
22.11.21
23:42
(0) внутри виртуалки никак
11 ДедМорроз
 
23.11.21
00:35
(6) Понятно,что к wmi должен быть доступ,но,если его нет,то и все остальные функции вернут не то.
Ну и понятно,что реальную частоту можно получить из регистров управления процессором,но для доступа к ним нужно писать драйвер,что достаточно нетривиально и зависит от железа.
Или использовать готового провайдера.
12 vovastar
 
23.11.21
00:40
(0) извиняюсь, но на фейхуа?
13 ansh15
 
23.11.21
10:56
Счетчики производительности никак не могут помочь?
Get-Counter -Counter "\Сведения о процессоре(*)\частота процессора" -Continuous
Показывает текущую частоту, если что-нибудь запустить на выполнение, она меняется.

Список доступных счетчиков
(Get-Counter -ListSet "Сведения о процессоре").Paths
14 Волшебник
 
модератор
23.11.21
11:02
(12) Вы теряете любопытство. Это признак надвигающейся старости.
15 rphosts
 
23.11.21
11:04
(12)свой микромонитор сервера, например
16 H A D G E H O G s
 
23.11.21
11:25
(15) Бинго!
17 polosov
 
23.11.21
11:30
(16) https://www.dfrobot.com/blog-1313.html
Там про температуру, но с частотой тоже можно будет.
18 polosov
 
23.11.21
11:33
+(17) В целом либа openHardwareMonitor'а много информации отдать может.
19 pechkin
 
23.11.21
11:52
(15) но зачем свой? программирование ради программирования?
ну в принципе тоже можно
20 Garykom
 
гуру
23.11.21
12:01
(18) там можно веб-сервер запустить и дергать из 1С
21 Garykom
 
гуру
23.11.21
12:03
(20)+ тупо html парсить из 1С
22 polosov
 
23.11.21
12:07
(20) Он там для того, чтобы с удаленных систем забирать данные самим openHardwareMonitor'ом. Что-то не нашел документации как его дергать программно.
23 rphosts
 
23.11.21
12:07
(19) развернуть в 1 клик, получать только то, что нужно, хранить в потребном формате логи....
мне вот всё то-ли времени то-ли желания не хватает утилитки контроля бэкапов (с дельтой прироста, хранением CRC, бла-бла-бла)... ну и да, программировать меня немного штырит
24 Garykom
 
гуру
23.11.21
12:10
(22) прекрасно дергается программно

https://github.com/openhardwaremonitor/openhardwaremonitor/blob/master/Utilities/HttpServer.cs
начинать с "private void SendJSON(HttpListenerResponse response) {"
25 polosov
 
23.11.21
12:12
(24) Так это генерация ответа сервером жи.
Ты лучше найди пример запроса к серверу.
26 Garykom
 
гуру
23.11.21
12:13
27 polosov
 
23.11.21
12:14
(26) О, ну если так просто, то это круто. Сча попробую
28 Garykom
 
гуру
23.11.21
12:15
(25) дык вы че в JS совсем не шарите?
оно же там https://i2.paste.pics/F2NQS.png
29 polosov
 
23.11.21
12:18
(28) Нет в JS не шарю.
Да, кстати json нормально получается и вся инфа в нем есть.
30 Кирпич
 
23.11.21
16:16
function CallNtPowerInformation(InformationLevel: Byte; lpInputBuffer: Pointer; nInputBufferSize: Longint; lpOutputBuffer: Pointer; nOutputBufferSize: Longint): Byte; stdcall; external 'PowrProf.dll';

фигню написал
результат функции и InformationLevel не должны быть byte
они размером по 4 байта
31 H A D G E H O G s
 
23.11.21
16:22
(30) Я брал откуда то с инета, поправил уже. Ну ты же понимаешь, что в худшем случае, даже с byte, был бы accessviolation, либо мусор в выходном буфере, но никак бы 4200 в 3600 МГЦ не превратились бы.
32 Кирпич
 
23.11.21
16:36
Я попробовал на ноуте. На таймер повесил. CurrentMhz показывает 1600, а когда питание от ноута отключаю, то 1400 становится
33 Кирпич
 
23.11.21
16:46
(31) мусор в выходном буфере у тебя не появится(он же у тебя не на стеке). Могут локальные переменные превратиться в непонятно что.
34 Кирпич
 
23.11.21
17:00
правда в этом случае повезло - на результат функции положен болт, а стек наверное выравнен по 4 байта и всё OK :)
35 Конструктор1С
 
23.11.21
17:14
(0) делфи жиф?
36 Garykom
 
гуру
23.11.21
17:17
(35) живее всех живых
и платная https://www.embarcadero.com/ru/products/delphi
и бесплатная https://www.lazarus-ide.org/
37 H A D G E H O G s
 
23.11.21
17:18
(33) Да, там динамический массив, в куче. Была бы локальная структурка или локальный фикс массив - мог бы появиться.