Показать сообщение отдельно
Старый 16.05.2011, 15:28   #1  
Logger is offline
Logger
Участник
Лучший по профессии 2015
Лучший по профессии 2014
 
3,973 / 3268 (116) ++++++++++
Регистрация: 12.10.2004
Адрес: Москва
Записей в блоге: 2
Измерение времени точнее чем Winapi::getTickcount()
Добрый день всем.

Появилась задача померять время точнее чем Winapi::getTickcount()
Попробовал применить функции win32Api
QueryPerformanceCounter
QueryPerformanceFrequency

Получился такой код (в 3-ке успешно работал)

X++:
// pkoz 08.01.2011
static int64 GRD_getQueryPerformanceCounter()
{
    #define.offset0(0)
//    #define.offset2(2)
    #define.offset4(4)
    #define.KernelDLL('KERNEL32')

    DLLFunction                     _getCounter ;
    DLL             _dll            = new DLL(#kernelDLL);
    int64           Counter;
    Binary          struct          = new Binary(8);
    _getCounter                  = new DLLFunction(_dll, 'QueryPerformanceCounter');
    _getCounter.returns(ExtTypes::Byte);
    _getCounter.arg(ExtTypes::Pointer);
    struct.dWord(#offset0,0);
    struct.dWord(#offset4,0);

    if (_getCounter.call(struct))
    {
        Counter =struct.qWord(#offset0);
    }
    return Counter;
}
X++:
static real GRD_getQueryPerformanceCounterDelta(
        int64   _iStart,
        int64   _koeff = 1000 // миллисекунды, если результат нужен в секундах, то передать 1
        )
{
    real        ret;
    int64       iEnd;
    int64       iDelta;
    int64       iFreq;
    ;
    iEnd   = Global::GRD_getQueryPerformanceCounter();
    iDelta = iEnd - _iStart;

    iFreq  = Global::GRD_getQueryPerformanceFrequency();
    ret = (iFreq == 0) ? 0 : iDelta / iFreq * _koeff;
    return ret;


}
X++:
// pkoz 08.01.2011
static int64 GRD_getQueryPerformanceFrequency()
{
    #define.offset0(0)
//    #define.offset2(2)
    #define.offset4(4)
    #define.KernelDLL('KERNEL32')

    DLLFunction                     _getFrequency ;
    DLL             _dll            = new DLL(#kernelDLL);
    //int            frequency;
    int64           frequency;
    Binary          struct          = new Binary(8);
    _getFrequency                  = new DLLFunction(_dll, 'QueryPerformanceFrequency');
    _getFrequency.returns(ExtTypes::Byte);
    _getFrequency.arg(ExtTypes::Pointer);
    struct.dWord(#offset0,0);
    struct.dWord(#offset4,0);

    if (_getFrequency.call(struct))
    {
        //frequency =struct.dWord(#offset0);
        //if (frequency<10000000)
        //    frequency= 0;
        //else
        //    frequency = real2int(round(frequency/1000000.0,1));

        //return frequency;
        frequency =struct.qWord(#offset0);
    }
    return frequency;
}
Но в 64-битном окружении он естественно не работает.
У кого-нить есть аналог работы со счетчиками работающий и в 64-м окружении ?
Полагаю, надо просто переложить эти функции на .Net вызовы. Сам переложить затруднился.