На главную Наши проекты:
Журнал   ·   Discuz!ML   ·   Wiki   ·   DRKB   ·   Помощь проекту
ПРАВИЛА FAQ Помощь Участники Календарь Избранное RSS
Дорогие друзья! Поздравляем вас с днём Победы!
msm.ru
Обратите внимание:
1. Прежде чем начать новую тему или отправить сообщение, убедитесь, что вы не нарушаете правил форума!
2. Обязательно воспользуйтесь поиском. Возможно, Ваш вопрос уже обсуждали. Полезные ссылки приведены ниже.
3. Темы с просьбой выполнить какую-либо работу за автора в этом разделе не обсуждаются.
4. Используйте теги [ code=cpp ] ...текст программы... [ /code ] для выделения текста программы подсветкой.
5. Помните, здесь телепатов нет. Старайтесь формулировать свой вопрос максимально грамотно и чётко: Как правильно задавать вопросы
6. Запрещено отвечать в темы месячной и более давности без веских на то причин.

Полезные ссылки:
user posted image FAQ Сайта (C++) user posted image FAQ Форума user posted image Наши Исходники user posted image Поиск по Разделу user posted image MSDN Library Online (Windows Driver Kit) user posted image Google

Ваше мнение о модераторах: user posted image B.V.
Модераторы: B.V.
Страницы: (3) 1 2 [3]  все  ( Перейти к последнему сообщению )  
> Ломается QueryPerformanceCounter. Как такое возможно?! , Странный эффект на пустом месте...
    Цитата jur @
    ближайшее время полностью перейду на OpenGL. Надеюсь, что там моего вопроса вообще не возникнет.

    Насколько помню там тоже самое.
      Цитата Qraizer @

      Автор рассказывает совершенно невероятные вещи.
      При этом цифра 100 ррм (и даже больше - до 1000!) вполне возможна.
      Но только не в связи с таинственным исчезновением прерываний,
      а по более прозаичным причинам.
      1. Всем наверно уже известно, что в ПК используются неудобные кварцы
      для точного отсчёта времени. Отсюда и проблемы хода часов.
      2. Дело в том, что качественные показатели кварца (допустим в 1ррм) не могут
      быть практически достигнуты в обычном кварцевом мультивибраторе.
      Качественные показатели - такие как точность начальной установки частоты,
      температурная стабильность, временная стабильность зависят также и от
      внешней обвязки - конденсаторов, вентилей цифровых микросхем, резисторов
      и даже индуктивностей. Если они используются в данном узле.
      В итоге, даже если мы подберём частоту(кварц+делитель) для часов теоретически
      абсолютно точно, реальная ошибка может составить и 0.1% - запросто.
      Для работы компа в целом это не страшно, а вот для часов это не здорово.
      3. если использовать кварцевый генератор - отдельный электронный компонент - тогда "да".
      Но его цена обычно на порядок (плюс-минус лапоть) выше стоимости обычных кварцев.
        Извиняюсь, если мой вопрос покажется неуместным, но честно говоря после чтения первого поста я вообще не понял в чём проблема! :-?
        Я честно говоря не понял в чем виноват DirectX, QueryPerformanceCounter и самое главное каким образом FPU или DirectX может влиять на QueryPerformanceCounter? Если многоуважаемые коллеги объяснили бы поподробнее, был бы признателен. Единственно в чем может быть виновата QueryPerformanceCounter, на мой взгяд, так это выдавать разные значения для разных ядер и то не всегда, но для этого можно сделать элементарную синхронизацию значений счетчиков для всех ядер.

        Во втором куске кода после рестарта компьютера(который автор приводит как пример нормальной работы) видно, что время также рассинхронно(сначала последовательно увеличивается, потом есть меньшие значения). Для того чтобы время в логе было более-менее синхронно необходимо делать один поток записывающий в лог-файл, он будет принимать данные от других потоков, сортировать и выводить в файл. А если просто закрыть вывод в файл критическими секциями и использовать буферизированный вывод, то в некоторые моменты будет происходить сброс кэша на диск и все остальные потоки будут ждать пока какой-то один из потоков не разгрузит дисковой и системный кеши. Из-за этого в файле протокола и будут появляться рассинхронные данные и задержки. Здесь была такая тема "Может ли критическая секция быть причиной тормозов".

        Цитата jur @
        Но выдача протокола закрыта критическими секциями и каждая строка записывается путем открытия/записи/закрытия файла протокола

        Вот это вообще не понял, а зачем открывать и закрывать файл, если и так стоят критические секции?

        p/s/ Ещё раз, прошу рассматривать мой пост только с точки зрения того, что я хотел бы лично для себя прояснить некоторые моменты которые не понял.
        Сообщение отредактировано: neokoder -
          Цитата neokoder @
          Я честно говоря не понял в чем виноват DirectX, QueryPerformanceCounter и самое главное каким образом FPU или DirectX может влиять на QueryPerformanceCounter? Если многоуважаемые коллеги объяснили бы поподробнее, был бы признателен

          DirectX устанавливает пониженную точность FPU-вычислений и тем самым загрубляет результаты не самого QueryPerformanceCounter, а его деления на frequency для получения секунд. Отсюда, 1) чем больше времени прошло со старта системы, тем заметнее погрешность, 2) в других потоках результаты не загрубляются, т.к. у каждого потока свои настройки FPU.

          PS: Основной вопрос был не о "рассинхронизации", а о том, что происходит заметное загрубление выдачи времени - сначала все строки имеют различающиеся значения, а потом идут пачками с одним и тем же значением
          Сообщение отредактировано: leo -
            Цитата leo @
            DirectX устанавливает пониженную точность FPU-вычислений и тем самым загрубляет результаты не самого QueryPerformanceCounter, а его деления на frequency для получения секунд. Отсюда, 1) чем больше времени прошло со старта системы, тем заметнее погрешность, 2) в других потоках результаты не загрубляются, т.к. у каждого потока свои настройки FPU.

            PS: Основной вопрос был не о "рассинхронизации", а о том, что происходит заметное загрубление выдачи времени - сначала все строки имеют различающиеся значения, а потом идут пачками с одним и тем же значением


            Понятно, leo. Но так можно вообще отказаться от деления, а переведение в секунды организовать самому, минуя FPU. Это же проще гораздо чем что-то там ещё придумывать.
              Я уже на это намекал, но в #29 автор заявил, что ему "важна точность сопроцессора (не фатально, но важно)" и для других расчетов
                Цитата neokoder @
                Я честно говоря не понял в чем виноват DirectX, QueryPerformanceCounter и самое главное каким образом FPU или DirectX может влиять на QueryPerformanceCounter?

                Тут все просто. DirectX портила точность вычислений с плавающей точкой, что косвенно проявляется в протоколе :-) Я сначала подумал, что строки с одинаковым временем получаются из-за сломавшегося QueryPerformanceCounter, но уважаемый коллега Адамантэус помог понять, в чем дело.

                Что касается разных ядер, то мне в общем-то до лампочки синхронизм между потоками. Тем более, что рассинхронизация, наверное, невелика.

                Цитата neokoder @
                Цитата jur @
                Но выдача протокола закрыта критическими секциями и каждая строка записывается путем открытия/записи/закрытия файла протокола
                Вот это вообще не понял, а зачем открывать и закрывать файл, если и так стоят критические секции?

                Все дело в том, что открытие/запись/закрытие файла протокола позволяет мне получить квазиатомарную операцию протоколирования. Т.е. критическая секция гарантирует, что один вызов вывода строки протокола будет полностью выполнен до следующего вызова даже из другого потока. А открытие/закрытие файла позволяет все-таки получить протокол даже в случае "вылета" программы. Я так сделал потому, что раньше получал пустой файл, если программа "вылетала". Ведь данные накапливаются в буфере, а в файл они не попадают.
                  Цитата jur @
                  Я так сделал потому, что раньше получал пустой файл, если программа "вылетала". Ведь данные накапливаются в буфере, а в файл они не попадают.

                  Сделайте лучше небуферизированный ввод/вывод. Открытие/закрытие файла отнимает кучу лишнего времени.
                  Сообщение отредактировано: neokoder -
                    Цитата leo @
                    DirectX устанавливает пониженную точность FPU-вычислений и тем самым загрубляет результаты не самого QueryPerformanceCounter, а его деления на frequency для получения секунд. Отсюда, 1) чем больше времени прошло со старта системы, тем заметнее погрешность, 2) в других потоках результаты не загрубляются, т.к. у каждого потока свои настройки FPU.

                    А что, автор делил именно так? Не дельту двух значений (которые целочисленные) делил на частоту, а сначала делил и потом вычислял дельту? Ой, мамочки :D
                      Цитата Pacific @
                      А что, автор делил именно так? Не дельту двух значений (которые целочисленные) делил на частоту, а сначала делил и потом вычислял дельту? Ой, мамочки

                      Вряд ли. Думаю должен быть где-то код типа такого:
                      ExpandedWrap disabled
                        double GetElapsedSeconds(__int64 c1,__int64 c2)
                        {
                           return ((double)(c2-c1)/double(_timer_frequency);
                        }
                        Да нет, вот тут: Ломается QueryPerformanceCounter. Как такое возможно?! (сообщение #3149130)
                        Такой код:
                        ExpandedWrap disabled
                          __int64 GetElapsedCount()
                            {
                              LARGE_INTEGER current_time;
                              if( !QueryPerformanceCounter(&current_time) ) return 0;
                              return current_time.QuadPart;
                            }
                           
                            double GetElapsedSeconds()
                            {
                              return double(GetElapsedCount()) / double(_timer_frequency);
                            }
                          Цитата Pacific @
                          А что, автор делил именно так? Не дельту двух значений (которые целочисленные) делил на частоту, а сначала делил и потом вычислял дельту? Ой, мамочки

                          Если бы он делил дельту, то возможно и не обнаружил бы проблему, т.к. она проявилась бы только через десятки-сотни секунд работы проги
                            Цитата leo @
                            Если бы он делил дельту, то возможно и не обнаружил бы проблему, т.к. она проявилась бы только через десятки-сотни секунд работы проги

                            НЕ БЫЛО БЫ СЧАСТЬЯ, ДА НЕСЧАСТЬЕ ПОМОГЛО ;)
                              Цитата neokoder @
                              Сделайте лучше небуферизированный ввод/вывод. Открытие/закрытие файла отнимает кучу лишнего времени.

                              Да, спасибо, я именно так и сделал. Уже не помню, почему раньше этот момент мне не понравился. Спасибо за полезную подсказку!

                              Цитата Pacific @
                              А что, автор делил именно так? Не дельту двух значений (которые целочисленные) делил на частоту, а сначала делил и потом вычислял дельту? Ой, мамочки

                              Не, не надо бояться :-) "Автор" так сделал... Ну как бы это сказать?... Ну так нужно было :-) (В некоторых случаях мне нужно время в системе, а не от запуска моей программы.)

                              Но! Этот момент вскрыл гораздо более важную вещь. А именно, ухудшение точности вычислений с плавающей точкой. На эти треклятые времена в протоколе можно наплевать, но удалось понять гораздо более важный вопрос. Поэтому Ваши слова: "... сначала делил и потом вычислял дельту", - это стирание двойки в дневнике, или, что намного хуже, исправление данных в анализе. Я очень рад, что анализ не исправлял, а с помощью друзей обнаружил источник болезни и нашел действенный метод ее лечения! :-)

                              Цитата neokoder @
                              Думаю должен быть где-то код типа такого:

                              Точно! Стопроцентное попадание :-) Вот мой нынешний код:

                              ExpandedWrap disabled
                                  __int64 GetElapsedCount()
                                  {
                                    LARGE_INTEGER current_time;
                                    if( !QueryPerformanceCounter(&current_time) ) return 0;
                                    return current_time.QuadPart;
                                  }
                                 
                                  double GetElapsedSeconds()
                                  {
                                    return double(GetElapsedCount()-_start_ticks) / _timer_frequency;
                                  }

                              Правда, раньше я _start_ticks не вычитал, из-за причины, изложенной выше.

                              Цитата neokoder @
                              НЕ БЫЛО БЫ СЧАСТЬЯ, ДА НЕСЧАСТЬЕ ПОМОГЛО

                              Именно так :-)
                              Сообщение отредактировано: jur -
                              1 пользователей читают эту тему (1 гостей и 0 скрытых пользователей)
                              0 пользователей:
                              Страницы: (3) 1 2 [3]  все


                              Рейтинг@Mail.ru
                              [ Script execution time: 0,0430 ]   [ 15 queries used ]   [ Generated: 10.05.24, 19:46 GMT ]