CPU speed

Тема в разделе "WASM.WIN32", создана пользователем RamMerLabs, 27 ноя 2006.

  1. RamMerLabs

    RamMerLabs Well-Known Member

    Публикаций:
    0
    Регистрация:
    11 сен 2006
    Сообщения:
    1.426
    как измерить скорость проца?
    зы: знаю, что через rdtsc, но не всегда работает на pentium4.

    кто знает - помогите исходником на асме, плз!
     
  2. Quantum

    Quantum Паладин дзена

    Публикаций:
    0
    Регистрация:
    6 янв 2003
    Сообщения:
    3.143
    Адрес:
    Ukraine
    RamMerLabs
    Как ты меряешь?

    Самый ламерский способ (аля Delphi):
    t0 = rdtsc
    Sleep(1000)
    t1 = rdtsc
    speed = t1 - t0

    How can I tell CPU speed?
     
  3. RamMerLabs

    RamMerLabs Well-Known Member

    Публикаций:
    0
    Регистрация:
    11 сен 2006
    Сообщения:
    1.426
    меряю так:

    Код (Text):
    1. long GetCpuFrequency()
    2. {
    3.  DWORD dwPriorityClass = ::GetPriorityClass(::GetCurrentProcess());
    4.  DWORD dwThreadPriority = ::GetThreadPriority(::GetCurrentThread());
    5.  ::SetPriorityClass(::GetCurrentProcess(), REALTIME_PRIORITY_CLASS);
    6.  ::SetThreadPriority(::GetCurrentThread(), THREAD_PRIORITY_TIME_CRITICAL);
    7.  ::Sleep(1);
    8.  LARGE_INTEGER FR, C1, C2;
    9.  if (! ::QueryPerformanceFrequency(&FR)) return 0;
    10.  ::QueryPerformanceCounter(&C1);
    11.  C2.QuadPart = C1.QuadPart;
    12.  INT64 T1, T2;
    13.  while (C2.LowPart == C1.LowPart)
    14.  {
    15.   ::QueryPerformanceCounter(&C1);
    16.   __asm
    17.   {
    18.    rdtsc
    19.    mov dword ptr [T1+0], eax
    20.    mov dword ptr [T1+4], edx
    21.   }
    22.  }
    23.  __asm mov esi, 200000
    24. repeat:
    25.  __asm
    26.  {
    27.   xor eax, eax
    28.   xor ebx, ebx
    29.   xor ecx, ecx
    30.   xor edx, edx
    31.   cpuid
    32.   sub esi, 1
    33.   jg repeat
    34.  }
    35.  ::QueryPerformanceCounter(&C2);
    36.  __asm
    37.  {
    38.   rdtsc
    39.   mov dword ptr [T2+0], eax
    40.   mov dword ptr [T2+4], edx
    41.  }
    42.  ::SetPriorityClass(::GetCurrentProcess(), dwPriorityClass);
    43.  ::SetThreadPriority(::GetCurrentThread(), dwThreadPriority);
    44.  ::Sleep(1);
    45.  return (long) double((T2 - T1) * double(FR.QuadPart) / double(C2.QuadPart - C1.QuadPart));
    46. }
     
  4. RamMerLabs

    RamMerLabs Well-Known Member

    Публикаций:
    0
    Регистрация:
    11 сен 2006
    Сообщения:
    1.426
    кроме того критично время измерения: не более 0,1 сек
     
  5. RamMerLabs

    RamMerLabs Well-Known Member

    Публикаций:
    0
    Регистрация:
    11 сен 2006
    Сообщения:
    1.426
    вы че там спите что-ли?
     
  6. Quantum

    Quantum Паладин дзена

    Публикаций:
    0
    Регистрация:
    6 янв 2003
    Сообщения:
    3.143
    Адрес:
    Ukraine
    RamMerLabs
    Я уже сказал, что использовать Sleep() - это ламерский способ, хотя более-менее рабочий, если использовать задержки > 1s. Можно в цикле вызывать GetSystemTime вместо Sleep(1), но это не намного лучше. В той статье описаны более продвинутые способы, но под win32 в 3м колце они, конечно, не работают.

    ЗЫ: Совсем забыл! timeBeginPeriod(1) перед вызовом Sleep повышает точность задержки, о чём в форуме уже неоднократно упоминал S_T_A_S_
     
  7. Noble Ghost

    Noble Ghost New Member

    Публикаций:
    0
    Регистрация:
    28 апр 2004
    Сообщения:
    204
    Адрес:
    Russia
    оффтопик.
    интересно, в каком случае это может быть критично?
     
  8. khv_test

    khv_test New Member

    Публикаций:
    0
    Регистрация:
    30 июн 2004
    Сообщения:
    135
    можно через DMI вот дока со стандартом
    h++p://www.dmtf.org/standards/published_documents/DSP0134.pdf
    там читается 65кб памяти с 000F0000h по 000FFFFFh и парсится SMBIOS структуры согласно доки
    для справки класс 04 Processor Information offset 16h.
     
  9. leo

    leo Active Member

    Публикаций:
    0
    Регистрация:
    4 авг 2004
    Сообщения:
    2.542
    Адрес:
    Russia
    Quantum
    Если замерять "истинный" интервал по QueryPerformance, то и Sleep(X) сойдет ;)
    Если почистить код RamMerLabs от непонятного мусора, то
    Код (Text):
    1. f rq 1
    2. c1 rq 1
    3. c2 rq 1
    4. tsc rq 1
    5.   invoke QueryPerformanceFrequency,f
    6.   invoke QueryPerformanceCounter,c1
    7.   rdtsc
    8.   mov dword[tsc],eax
    9.   mov dword[tsc+4],edx
    10.   invoke Sleep,100
    11.   rdtsc
    12.   sub eax,dword[tsc]
    13.   sbb edx,dword[tsc+4]
    14.   mov dword[tsc],eax
    15.   mov dword[tsc+4],edx
    16.   invoke QueryPerformanceCounter,c2
    17.   fild qword[tsc]
    18.   fild qword[f]
    19.   fild qword[c2]
    20.   fild qword[c1]
    21.   fsubp
    22.   fdivp
    23.   fmulp
    24.   fistp qword[tsc]
    С реал-тайм приоритетом дает вполне приемлемую точность на уровне 10^(-5)
    PS: А точнее наверное и невозможно из-за нестабильности частоты проца
     
  10. khv_test

    khv_test New Member

    Публикаций:
    0
    Регистрация:
    30 июн 2004
    Сообщения:
    135
    тут на С++ взято с h++p://crystalmark.info/ файл CrystalCPUID48Src.zip
    там многа тонкостей есть в сорсах...
     
  11. Cr4sh

    Cr4sh New Member

    Публикаций:
    0
    Регистрация:
    17 апр 2006
    Сообщения:
    668
    >> как измерить скорость проца?

    т.е. тактовую частоту?
    Код (Text):
    1. inline unsigned __int64 GetCycleCount(void)
    2. {
    3.     _asm
    4.     {
    5.         _emit 0x0F;
    6.         _emit 0x31;
    7.     }
    8. }
    9.  
    10. unsigned __int64 GetCPUSpeed(void)
    11. {
    12.     unsigned __int64 startcycle, speed, num, num2;
    13.  
    14.     do {
    15.         startcycle = GetCycleCount();
    16.         Sleep(1000);
    17.         speed = ((GetCycleCount() - startcycle) / 1000000);
    18.     } while (speed > 1000000);
    19.  
    20.     num = speed % 100;
    21.     num2 = 100;
    22.     if (num < 80) num2 = 75;
    23.     if (num < 71) num2 = 66;
    24.     if (num < 55) num2 = 50;
    25.     if (num < 38) num2 = 33;
    26.     if (num < 30) num2 = 25;
    27.     if (num < 10) num2 = 0;
    28.     speed = (speed-num)+num2;
    29.  
    30.     return speed;
    31. }
    зы: код не мой, но вроде работает
     
  12. Quantum

    Quantum Паладин дзена

    Публикаций:
    0
    Регистрация:
    6 янв 2003
    Сообщения:
    3.143
    Адрес:
    Ukraine
    leo
    Обычно точности до 1й десятой гигагерца достаточно, imho, хотя устовие критичности времени измерения натакивает на мысль, что задача решается в не совсем стандартных условиях, но автор, видимо, так и не откроет нам тайну.

    Cr4sh
    Это что-то новое :) Цепочка if'ов в конце, видимо, для округления.
     
  13. Pavia

    Pavia Well-Known Member

    Публикаций:
    0
    Регистрация:
    17 июн 2003
    Сообщения:
    2.409
    Адрес:
    Fryazino
    khv_test
    DMI - не точная вещь. Особенно что косается процессора и его частоты, многии на это жалуются.