C: usleep()

Založil Roman Horník, 13. 05. 2015, 20:22:15

Předchozí téma - Další téma

Roman Horník

Nazdar,

na starý kolena jsem byl nucen utkat se s Céčkem. Potřeboval jsem upravit jeden program, což se mi kupodivu povedlo, ačkoliv ta úprava není zrovna triviální a Céčku rozumím jak koza petrželi.
Mám potíže s usleep(), totiž očekával jsem od něj nějakou přesnost a ne, že nastavím prodlevu 1000µs (1ms) a ve skutečnosti bude třeba 915µs (měřeno pomocí bashovýho time; zabalil jsem inkriminovanej kód se čtyřma prodlevama 1ms do cyklu for() a nechal pomocí něj vykonat 10000 iterací - namísto 40s to běželo jen 36.6s), při delších prodlevách jsou skutečný prodlevy naopak delší jak nastavený (třeba 50ms > 54ms).
Proto se ptám, nedá se zajistit prodleva přesnější (třeba odvozená z taktu procesoru, FSB aj.)?
Debian Sid/Experimental 64bit + Mate Desktop Environment
* CPU: Intel i5 3570
* GPU: NVIDIA GTX650 1GD5
* MB: Lenovo IH61M
* RAM: 16GiB Deutsche Demokratische Republik 3 @ 1600MHz

jmp

ten petržel je dobrý...  ;D

dle jedné reakce při řešení tohoto problému to vypadá na limitaci standardního kernelu (není realtime...)
zahlédl jsem to zde: http://boards.dingoonity.org/dingux-development/accuracy-problem-with-usleep/

Roman Horník

Debian Sid/Experimental 64bit + Mate Desktop Environment
* CPU: Intel i5 3570
* GPU: NVIDIA GTX650 1GD5
* MB: Lenovo IH61M
* RAM: 16GiB Deutsche Demokratische Republik 3 @ 1600MHz

Roman Horník

Tak jsem zjistil, že to asi má co dočunění s konfigurací jádra, s frekvencí časovače přerušení (CONFIG_HZ). Původní hodnota je 250Hz (4ms; i když ve skutečnosti je to fCONFIG_HZ * nCPU, takže u mně na dvoujádru je to 250 * 2 = 500Hz = 2ms), a tak jsem si překonfiguroval jádro 4.1 na frekvenci víc jak desetinásobnou, na 2.52kHz (respektive 5.04kHz), což je milióntina frekvence CPU. Zdá se to teď bejt o řád přesnější.
Debian Sid/Experimental 64bit + Mate Desktop Environment
* CPU: Intel i5 3570
* GPU: NVIDIA GTX650 1GD5
* MB: Lenovo IH61M
* RAM: 16GiB Deutsche Demokratische Republik 3 @ 1600MHz

Roman Horník

#4
Jo, je to tak  :P

Když někoho napadne kompilovat jádro, tak před jeho konfigurací se upraví soubor kernel/Kconfig.hz, a sice nějak takhle:

#
# Timer Interrupt Frequency Configuration
#

choice
   prompt "Timer frequency"
   default HZ_250
   help
    Allows the configuration of the timer frequency. It is customary
    to have the timer interrupt run at 1000 Hz but 100 Hz may be more
    beneficial for servers and NUMA systems that do not need to have
    a fast response for user interaction and that may experience bus
    contention and cacheline bounces as a result of timer interrupts.
    Note that the timer interrupt occurs on each processor in an SMP
    environment leading to NR_CPUS * HZ number of timer interrupts
    per second.


   config HZ_100
      bool "100 HZ"
   help
     100 Hz is a typical choice for servers, SMP and NUMA systems
     with lots of processors that may show reduced performance if
     too many timer interrupts are occurring.

   config HZ_250
      bool "250 HZ"
   help
    250 Hz is a good compromise choice allowing server performance
    while also showing good interactive responsiveness even
    on SMP and NUMA systems. If you are going to be using NTSC video
    or multimedia, selected 300Hz instead.

   config HZ_300
      bool "300 HZ"
   help
    300 Hz is a good compromise choice allowing server performance
    while also showing good interactive responsiveness even
    on SMP and NUMA systems and exactly dividing by both PAL and
    NTSC frame rates for video and multimedia work.

   config HZ_1000
      bool "1000 HZ"
   help
    1000 Hz is the preferred choice for desktop systems and other
    systems requiring fast interactive responses to events.

   config HZ_2520
      bool "2520 HZ"
   help
    2520 Hz - tohle si zvolíš.


endchoice

config HZ
   int
   default 100 if HZ_100
   default 250 if HZ_250
   default 300 if HZ_300
   default 1000 if HZ_1000
   default 2520 if HZ_2520

config SCHED_HRTICK
   def_bool HIGH_RES_TIMERS


..a tahle nastavená frekvence se zvolí při konfiguraci v Processor type and features > Timer frequency (blablabla HZ):


Po kompilaci a instalaci jádra a nabootování do něj by to mělo chodit.

Když bejvával tzv. Zen kernel, což byla jakási modifikace standardního jádra, bylo možný si tam zvolit frekvenci 10kHz. Podle mně asi dost zbytečný, ale kdo chce, ať to zkusí.
Reakce systému by s rychlejším časovačem měly bejt přesnější a rychlejší, chod plynulejěí, ALE za cenu o trošku vyšší režie jádra, tzn. že disponibilní výpočetní výkon může bejt lehce nižší. Ale myslím si, že takovejm gamerům by tohle mohlo vyhovovat.
Debian Sid/Experimental 64bit + Mate Desktop Environment
* CPU: Intel i5 3570
* GPU: NVIDIA GTX650 1GD5
* MB: Lenovo IH61M
* RAM: 16GiB Deutsche Demokratische Republik 3 @ 1600MHz