PHP getrusage () yanlış bilgi döndüren?

2 Cevap php

Ben PHP CPU kullanımını belirlemek için çalışıyorum. Ben sadece sistem ve kullanıcı CPU kullanım süresi (Bölüm 4) bulmak için nasıl ayrıntıları this article hangi bulundu.

Ben örnekler denedim Ancak, ben tamamen farklı sonuçlar aldı.

first example:

sleep(3);

$data = getrusage();
echo "User time: ".
    ($data['ru_utime.tv_sec'] +
    $data['ru_utime.tv_usec'] / 1000000);
echo "System time: ".
    ($data['ru_stime.tv_sec'] +
    $data['ru_stime.tv_usec'] / 1000000);

Sonuçlar:

User time: 29.53
System time: 2.71

Example 2:

for($i=0;$i<10000000;$i++) {

}

// Same echo statements

Sonuçlar:

User time: 16.69
System time: 2.1

Example 3:

$start = microtime(true);  
while(microtime(true) - $start < 3) {  

}  

// Same echo statements

Sonuçlar:

User time: 34.94
System time: 3.14

Obviously, none of the information is correct Üçüncü örnekte belki sistem zamanı hariç. Yani ne yanlış yapıyorum? Ben gerçekten bu bilgileri kullanmak mümkün olmak istiyorum, ama güvenilir olması gerekir.

Ben Ubuntu 8.04 LTS Server uygulama (32-bit) kullanıyorum ve bu çıkış php -v:

PHP 5.2.4-2ubuntu5.10 with Suhosin-Patch 0.9.6.2 (cli) (built: Jan  6 2010 22:01:14)
Copyright (c) 1997-2007 The PHP Group
Zend Engine v2.2.0, Copyright (c) 1998-2007 Zend Technologies

2 Cevap

Dışarıdan bu bilgileri doğrulamak için sistem 'zaman' komutunu kullanabilirsiniz:

/usr/bin/time php script.php

gibi bir şeyler yazdırmak hangi:

0.03user 0.00system 0:03.04elapsed 0%CPU (0avgtext+0avgdata 32752maxresident)k
0inputs+0outputs (0major+2234minor)pagefaults 0swaps

Tabii ki, dont't getrusage () bilgisi () duvar saati zamanı CPU kullanıldığında zaman ve microtime olduğunu unutmayın. Program duvardaki saate göre 10 dakika çalışabilir, ama sadece dahili CPU süresinin birkaç saniye kullanabilirsiniz. Sonra tüm arka plan programları sistemi, kaynak çekişme, artı düzenli temizlik üzerinde çalışan CPU süre orada yarışma oluyor.

Bu kadar kısa süreler için doğru bir zamanlama elde edebilmek için ilgili çok sayıda faktör var. Eğer döngü while(microtime()) sürümü üç çalışır yapıyor, ben şu zamanlamaları var:

user: 0.98, 0.09, 0.90 sys: 0.12, 0.05, 0.94

Açıkçası oldukça varyans. Hatta sadece basit bir <? print_r(getrusage()) ?> 0-0,03 arasında değişen utime / stimes vardır.

Uzun süre için döngüler çalıştırmayı deneyin ve cpu kullanımını artırmak için içlerinde bir şeyler yapmak. Sağ şimdi numaralar doğru ölçmek için çok küçük.

Sayesinde Marc B's advice, ben gülünç kısa süreleri getrusage() 's hesaplamalarda hatalara neden olduğunu anlamaya başardı.

Ben bu yanlış numaralar atmak için bir iş çevresinde oluşturduk. İşte kod:

define('SCRIPT_START', microtime(1));

register_shutdown_function('record_activity');

/* Do work here */

function record_activity()
{
    $data = getrusage();
    $cpuu = ($data['ru_utime.tv_sec'] + $data['ru_utime.tv_usec'] / 1000000);
    $cpus = ($data['ru_stime.tv_sec'] + $data['ru_stime.tv_usec'] / 1000000);
    $renderedtime = round(microtime(1) - SCRIPT_START, 6);

    // Have some log function to put this info somewhere
    insert_record($renderedtime,
        //Only pass user CPU time if it's less than or equal to rendered time
        ($renderedtime >= $cpuu ? $cpuu : NULL ),
        //Only pass system CPU time if it's less than or equal to rendered time
        ($renderedtime >= $cpus ? $cpus : NULL ));
}

Umarım, bu aynı sorunu yaşayan başka herkes için yararlı olacaktır.