crossplatform.ru

Здравствуйте, гость ( Вход | Регистрация )

 
Ответить в данную темуНачать новую тему
> Новая библиотека boost::chrono, начиная с версии boost 1.47.0
Iron Bug
  опции профиля:
сообщение 10.11.2011, 12:52
Сообщение #1


Профессионал
*****

Группа: Модератор
Сообщений: 1611
Регистрация: 6.2.2009
Из: Yekaterinburg
Пользователь №: 533

Спасибо сказали: 219 раз(а)




Репутация:   12  


Собственно, сделаю тут небольшую заметку:
В boost версии 1.47.0 добавлена весьма занятная библиотека chrono:
http://www.boost.org/doc/libs/1_47_0/doc/html/chrono.html

Библиотека предлагает разнообразные функции для работы со временем. В том числе таймеры высокого разрешения (что было вечной проблемой при разработке под кроссплатформу).
Реализованы таймеры, функции для работы с временными интервалами, таймеры для измерения времени CPU, таймеры для измерения времени, затраченного потоками. Можно создавать собственные клоки (таймеры с прерыванием типа стробов).
Есть все виды конверсии к xtime. Есть функции для использования с boost::thread (sleep_for, sleep_until, try_lock_for, try_lock_until), пока они приведены в качестве примера, но уже идёт работа по включению их в состав boost::thread.

В общем, полезная и долгожданная библиотека. Окажется полезной тем, кто был вынужден изобретать велосипеды для скоростных таймеров :)

В ближайшее время буду тестировать эту библиотеку подробнее, о результатах напишу позже.
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
Iron Bug
  опции профиля:
сообщение 15.11.2011, 9:59
Сообщение #2


Профессионал
*****

Группа: Модератор
Сообщений: 1611
Регистрация: 6.2.2009
Из: Yekaterinburg
Пользователь №: 533

Спасибо сказали: 219 раз(а)




Репутация:   12  


Я провела серию тестов новой библиотеки.
Всё отлично работает: даже под вендой можно вести наносекундные измерения!

Для этого теста надо собрать буст с флагом BOOST_DATE_TIME_POSIX_TIME_STD_CONFIG (и сам тест с этим же флагом, соответственно), чтобы ptime давал наносекундное разрешение. В принципе, можно и вообще без него обойтись, тайминги нормально считаются в boost::chronoptime под вендой - нет, даже с флагом). Я сделала через ptime для this_thread::sleep() в моих рабочих программах: сам boost::chrono в boost::thread напрямую пока не поддерживается, но будет.
Конверсия стащена из песочницы буста и чуть переделана. Скоро это уже всё будет в самом бусте, без самодельных велосипедов. В рабочей версии уже многое переделано и добавлено, я наблюдаю за прогрессом.
Итак, код теста для венды (для линя проведу тест дома, чуть позже, в коде практически ничего не нужно менять):

Раскрывающийся текст
#include <Windows.h>
#include <boost/date_time/posix_time/posix_time.hpp>
#include <boost/chrono.hpp>
#include <vector>

using namespace std;
using namespace boost;

template < typename Duration>
posix_time::ptime convert_time_point_to_ptime(const chrono::time_point<chrono::high_resolution_clock, Duration>& from)
{
    typedef chrono::time_point<chrono::high_resolution_clock, Duration> time_point_t;
    typedef chrono::nanoseconds duration_t;
    typedef duration_t::rep rep_t;
    rep_t d = chrono::duration_cast<duration_t>(from.time_since_epoch()).count();
    rep_t sec = d/1000000000;
    rep_t nsec = d%1000000000;
    return  posix_time::from_time_t(0)+
        posix_time::seconds(static_cast<long>(sec))+
#ifdef BOOST_DATE_TIME_HAS_NANOSECONDS
        posix_time::nanoseconds(nsec);
#else
        posix_time::microseconds((nsec+500)/1000);
#endif
}

posix_time::ptime get_current_time()
{
    chrono::high_resolution_clock::time_point tp = chrono::high_resolution_clock::now();
    posix_time::ptime pt=convert_time_point_to_ptime(tp);
    return pt;
}


int main(int argc, char* argv[])
{
    int res = SetThreadPriority(GetCurrentThread(),THREAD_PRIORITY_TIME_CRITICAL);
    if(res != 0)
    {
        cout <<"Real time priority set" << endl;
    }
    vector <posix_time::time_duration> delays;
    for(int i=0; i<100; i++)
    {
        posix_time::ptime t = get_current_time();
        posix_time::time_duration d = t.time_of_day();
        delays.push_back(d);
    }
    res = SetThreadPriority(GetCurrentThread(),THREAD_PRIORITY_NORMAL);
    if(res != 0)
    {
        cout <<"Normal priority set" << endl;
    }
    posix_time::time_duration prev_d;
    for(vector<posix_time::time_duration>::iterator iter=delays.begin(); iter != delays.end(); iter++)
    {
        cout << iter->total_nanoseconds() - prev_d.total_nanoseconds() << endl;
        prev_d = *iter;
    }
    return 0;
}


Под вендой (семёрка, 64, core2duo 2.6GHz, release win32) получен результат:
(первое значение - мусор)
Раскрывающийся текст
Real time priority set
Normal priority set
12589068513489
4332
1575
1575
1182
1181
394
1575
394
788
1181
394
788
788
1575
394
787
394
788
394
1575
788
393
788
394
787
788
394
788
1181
788
787
394
788
394
787
394
788
394
787
394
788
394
1575
787
394
394
788
394
787
788
394
787
394
788
394
787
394
788
394
787
394
788
394
1575
787
788
394
788
393
788
394
788
393
788
394
787
394
788
394
787
394
788
394
787
394
788
394
787
394
788
394
787
394
788
1181
788
787
394
788


Причём если запускать ещё сам процесс с REALTIME приоритетом, то выходит примерно то же самое, но без выскоков за 2 мкс:
Раскрывающийся текст
Real time priority set
Normal priority set
12645134127255
3938
1575
788
788
1181
394
788
787
394
788
394
787
394
788
787
394
394
394
394
1181
394
788
393
394
394
394
788
393
788
788
394
393
394
394
394
787
394
394
394
394
787
394
1182
394
393
394
394
788
393
394
394
394
394
787
394
394
394
394
787
394
394
394
394
1181
394
788
393
394
394
394
788
393
394
394
394
394
393
788
394
394
394
393
394
788
394
394
393
394
788
394
393
394
394
394
1575
394
394
788
393


Собственно, это и есть предельная скорость работы венды при тупом поллинге в консоли. Кстати, проц при этом загружен только на 50%. Видимо, полностью грузит одно из ядер. Можно было даже выделить потоку отдельный проц, но мне стало лень, а для теста это несущественно.

Сообщение отредактировал Iron Bug - 15.11.2011, 10:46
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
ViGOur
  опции профиля:
сообщение 15.11.2011, 13:36
Сообщение #3


Мастер
******

Группа: Модератор
Сообщений: 3296
Регистрация: 9.10.2007
Из: Москва
Пользователь №: 4

Спасибо сказали: 231 раз(а)




Репутация:   40  


Цитата
даже под вендой можно вести наносекундные измерения!
Но как? Если винда не система реального времени!
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
Iron Bug
  опции профиля:
сообщение 15.11.2011, 16:04
Сообщение #4


Профессионал
*****

Группа: Модератор
Сообщений: 1611
Регистрация: 6.2.2009
Из: Yekaterinburg
Пользователь №: 533

Спасибо сказали: 219 раз(а)




Репутация:   12  


Цитата(ViGOur @ 15.11.2011, 16:36) *
Но как? Если винда не система реального времени!

ну, естессна, не фонтан! под линём задержки порядка единиц наносекунд. но всё-таки хоть что-то!
все мои тесты обычно давали разницу от 5 до 10 раз по задержкам по сравнению с линём, даже на самых лучших компиляторах.
просто до этого тупо было можно юзать из стандартных средств только кривой таймер, который тикал раз в 15600 микросекунд. а из нестандартных нужно было городить чёрти что (это чёрти что я где-то тут приводила в теме про скоростной таймер). теперь велосипед значительно упростился.
я напишу классы с таймерами. у меня была идея, но мелкософт, как всегда, не до конца реализовал стандарт С++x0 и пока под MSVS это нельзя реализовать, хотя gcc поддерживает фичу аж с 2006 года и MinGW поддерживает. кроме тормозной системы они ещё и самый тупой и отсталый компилятор умудрились создать :)

вот я как раз перекомпилила буст с нужным флагом и проверила под линём:
машина слабее! core2duo 1.86GHz, debian unstable, 64, ядро 3.0.0-2, release:
Раскрывающийся текст
8245120072742
68622
2997
369
187
336
175
161
160
351
161
160
160
165
160
161
160
448
160
161
160
161
160
165
160
175
161
160
161
164
160
161
160
605
160
161
160
161
164
161
160
160
161
160
165
160
161
160
161
160
164
161
160
161
160
161
164
160
161
160
161
160
164
161
160
1053
175
175
161
160
161
160
165
160
160
161
160
161
164
161
160
161
160
160
165
160
161
160
161
160
164
161
160
161
160
161
164
175
161
160

вот и сравни тайминги. проц в полтора раза слабее, плюс у меня тут дома запущена куча демонов, по сети идёт жирный обмен, открыто стопицот приложений, и прочее, и прочее. а на работе голая венда без нагрузки тестировалась.

Сообщение отредактировал Iron Bug - 15.11.2011, 18:35
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
ViGOur
  опции профиля:
сообщение 15.11.2011, 20:02
Сообщение #5


Мастер
******

Группа: Модератор
Сообщений: 3296
Регистрация: 9.10.2007
Из: Москва
Пользователь №: 4

Спасибо сказали: 231 раз(а)




Репутация:   40  


Хм, не знал. Спасибо за объяснение. :)
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
Iron Bug
  опции профиля:
сообщение 16.11.2011, 13:35
Сообщение #6


Профессионал
*****

Группа: Модератор
Сообщений: 1611
Регистрация: 6.2.2009
Из: Yekaterinburg
Пользователь №: 533

Спасибо сказали: 219 раз(а)




Репутация:   12  


Цитата(ViGOur @ 15.11.2011, 23:02) *
Хм, не знал. Спасибо за объяснение. :)

ну, просто тут хоть какой-то прогресс наметился в области таймеров. конечно, это не системное решение, а чисто софтовое. но тем не менее.
таймеры высокого разрешения - это самая грустная тема в программировании, особенно кроссплатформенном. причём проблема-то высосана из пальца: на материнке стоит контроллер таймера, он элементарно программируется. почему бы не предоставить юзеру если не возможность управления, то хотя бы считывание счётчиков? вроде бы вполне себе логично.
однако, стандартные библиотечные таймеры системы под линём дают максимум микросекундную точность. а под вендой они и вовсе дают почему-то интервал в около 15.6 миллисекунд (это стандартный интервал для венды 7, он может меняться примерно в интервале 10 до 20мс, но это всё равно слишком дофига). поэтому приходилось извращаться со счётчиком тиков. теперь это извращение (а это реализовано именно так, я смотрела код) сделано в виде стандартной кроссплатформенной библиотеки, с довольно удобным интерфейсом.
собственно, если я одолею некоторые трудности с темплейтами, то я сделаю набор файлов для удобной работы потоков с этим таймером. это сейчас у меня главная задача для нового проекта: привести все тайминги в порядок, по возможности.

ну и кроме всего, когда юзеры начинают сравнивать системы... я точно знаю, почему конкретно я не люблю венду. вот просто абсолютно, в деталях, по пунктам. как программист, я вижу совершенно непроходимые тупики в её развитии и кучу багов, которые они совсем не торопятся исправлять. я не хочу её ругать, потому что я уже устала это делать :) поэтому я приспосабливаюсь к её кривостям, как могу, и делюсь своими открытиями с другими :)

Сообщение отредактировал Iron Bug - 20.11.2011, 1:09
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
ViGOur
  опции профиля:
сообщение 16.11.2011, 20:44
Сообщение #7


Мастер
******

Группа: Модератор
Сообщений: 3296
Регистрация: 9.10.2007
Из: Москва
Пользователь №: 4

Спасибо сказали: 231 раз(а)




Репутация:   40  


Цитата(Iron Bug @ 16.11.2011, 14:35) *
это стандартный интервал для венды 7, он может меняться примерно в интервале 10 до 20мс, но это всё равно слишком дофига
Ну это уже меньше чем раньше, помнится в msdn'e достаточно давно вычитал, что было +-100, а тут уже всего 10-20, получается прогресс налицо! :)
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение

Быстрый ответОтветить в данную темуНачать новую тему
Теги
Нет тегов для показа


1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0




RSS Текстовая версия Сейчас: 28.3.2024, 19:33