На главную Наши проекты:
Журнал   ·   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. Как такое возможно?! , Странный эффект на пустом месте...
    А видеодрова пробовал обновлять? Есть подозрение, что кривая инициализация D3D-минипорта может MMX-ом испортить FPU.
      Цитата Qraizer @
      А видеодрова пробовал обновлять? Есть подозрение, что кривая инициализация D3D-минипорта может MMX-ом испортить FPU.

      За время борьбы с этой напастью я сменил два или три раза дрова на две разные видеокарты (обе NVIDIA, одна 8400, другая 9500, буквы запамятовал) на двух компьютерах. Кроме того пробовал на довольно слабом Целероне, где видеоподсистема вообще встроенная (если не путаю, на Интеловском ускорителе).

      Все едино... Как только счетчик RDTSC достигает достаточно большой величины, время в протоколе портится. Это, кстати, объясняет, почему после перезагрузки компа все работает нормально. Просто значение счетчика еще маленькое, в мантиссу еще более-менее помещается! :-)
        А у тебя случаем не float? Может банально переполняется и надо использовать double?
          Ясно. Причина хоть и ясна, но не локализована.
            Цитата Pavia @
            А у тебя случаем не float? Может банально переполняется и надо использовать double?

            Не, все нормально, я использую такой метод:

            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);
                }

            где приватная переменная класса:

            __int64 _timer_frequency;

            устанавливается в конструкторе. Видать сопроцессор как-то так ломается, что даже double обрабатываются, как float. Без понятия, как и зачем это делается.

            Цитата Qraizer @
            Ясно. Причина хоть и ясна, но не локализована.

            Не представляю, как ее локализовать. Ведь эта DirecX - черный Биллевский ящик :-)

            P.S. Я вообще на OpenGL перехожу :-) Т.к. мне в приборе (в некоторых вариантах) нужно использовать OpenGL ES. Подозреваю, что там этой засады не будет. Обязательно проверю.
              Цитата jur @
              Тогда я после создания устройства DirecX вставил простую конструкцию FINIT

              Цитата jur @
              Видать сопроцессор как-то так ломается, что даже double обрабатываются, как float. Без понятия, как и зачем это делается.

              FINIT это очень "грубо и невоспитанно", т.к. она не только устанавливает макс.точность вычислений, но и маскирует все исключения FPU - и то, и другое может аукнуться на работе того же DirectX или твоих собственных вычислениях. Открой для себя ф-ии controlfp\control87, которые позволяют проверять, сохранять и устанавливать управляющее слово FPU, как целиком так и отдельные биты\поля, в частности точность вычислений
              Сообщение отредактировано: leo -
                Ну, странно, что проблема только у тебя, не правда ли?
                Цитата jur @
                Не представляю, как ее локализовать. Ведь эта DirecX - черный Биллевский ящик :-)
                Это как ничто мотивирует читать документацию.
                Цитата jur @
                Цитата Pavia @
                А у тебя случаем не float? Может банально переполняется и надо использовать double?

                Не, все нормально, ...
                Итог: о флаге D3DCREATE_FPU_PRESERVE ты впервые слышишь? Я признаться тоже, но я почитал документацию.
                Сообщение отредактировано: Qraizer -
                  Цитата Qraizer @
                  о флаге D3DCREATE_FPU_PRESERVE ты впервые слышишь? Я признаться тоже, но я почитал документацию

                  Угу, и если с reduce performance все понятно, то unmasking these exceptions may result in undefined behavior - как-то настораживает и заставляет задуматься, а нужно ли использовать этот флаг ради какой-то одной операции расчета времени в секундах, когда можно и целочисленным делением обойтись для получения микросекунд (а затем, если очень хочется поставить разделительную точку в строке в нужном месте), ну или дергать controlfp до и после вычисления секунд
                    Эти самые Portions of Direct3D, которые assume, что floating-point unit exceptions are masked, скорее всего тоже задокументированы. Но если и нет или не охота париться, можно и самому замаскировать той же _controlfp(), т.к. вряд ли они интересуют jur.
                      Цитата leo @
                      Открой для себя ф-ии controlfp\control87, которые позволяют проверять, сохранять и устанавливать управляющее слово FPU, как целиком так и отдельные биты\поля, в частности точность вычислений

                      Большое спасибо за толковую подсказку! (Я подозревал, что должна быть функция API для этого дела. Ведь не замыкаться же в Ассемблере...) Это как раз то, что нужно. А то я совсем растерялся, куды бечь - не знаю... :-)

                      Цитата Qraizer @
                      Итог: о флаге D3DCREATE_FPU_PRESERVE ты впервые слышишь? Я признаться тоже, но я почитал документацию.

                      Да, про этот флаг я не знал. И, честно говоря, не догадался поискать именно его. Т.к. за много лет привык, что в Винде "дело спасения утопающих - дело рук самих утопающих"... :-)

                      Подсказка уважаемого leo подтолкнула меня к дальнейшим действиям. Провел некоторые исследования. С помощью функции _controlfp_s() я прочитал слово состояния FPU перед инициализацией DirecX и после создания DX-устройства:

                      ExpandedWrap disabled
                        [0.09747] [PlotEngineR2] CRenderer::Init: Original FPU control word 0x9001F
                        [0.10028] [PlotEngineR2] CRenderer::Init: DX Object   = 0x00173E20
                        [0.10054] [PlotEngineR2] CRenderer::Init: GetAdapterDisplayMode() OK
                        [0.12500] [PlotEngineR2] CRenderer::Init: DX Device   = 0x0017D760
                        [0.12500] [PlotEngineR2] CRenderer::Init: Altered FPU control word 0xA001F, changed bits 0x30000

                      Посмотрел по битам - так и есть: точность вычислений ухудшается.

                      Ладно, думаю, а что делают FINIT/FNINIT и _clearfp()? Оказалось, что ассемблерная команда возвращает слово состояния в первоначальный вид, т.е. 0x9001F, а функция сброса - как раз в ДиректИксовский вид 0xA001F, во как!

                      Тогда я попробовал применить конструкцию, устанавливающую FPU в значение по умолчанию:

                      ExpandedWrap disabled
                          _controlfp_s(&fpu_control_word, _CW_DEFAULT, MCW_PC);

                      Все OK. Стал размышлять, на каком именно варианте остановиться? Ведь можно также сохранять/восстанавливать слово состояния FPU. Получилось бы то же самое. Однако логичнее, IMHO, сохранять/восстанавливать, а не сбрасывать в дефолт. Ведь может быть какой-нибудь модуль установит свой, нужный ему, режим работы.

                      Большое спасибо за помощь, друзья! :-)
                        ИМХО самым правильным будет использовать D3DCREATE_FPU_PRESERVE, потому как ты явно говоришь DirectX-у, чтоб он не трогал FPU, и он становится в курсе происходящего. Если ты это сделаешь сохранением MCW с последующим его восстановлением, DirectX не будет в курсе этого, т.к. ты добился того же, но за его спиной. Это может повлечь ещё какие-нибудь грабли.
                        Что касается FPU-исключений, то их следует либо действительно запретить, раз того хотят Portions of Direct3D, либо, если они нужны программе, поставить "глобальный" SEH-кадр, который будет их ловить, в __except()-выражении фильтровать, и если вдруг они придут из недр DirectX-а, избавляться от них прям на месте и возвращать EXCEPTION_CONTINUE_EXECUTION. Избавляться, думаю, следует эмуляцией маскированной реакции FPU на это исключение.
                          Цитата Qraizer @
                          ИМХО самым правильным будет использовать D3DCREATE_FPU_PRESERVE, потому как ты явно говоришь DirectX-у, чтоб он не трогал FPU, и он становится в курсе происходящего

                          Это будет самым неправильным решением, т.к. раз DirectX используется, значит это нужно, и тормозить его работу ради вычисления какой-то одной цифирьки какого-то лога - выглядит просто глупо. Вот если в проге юзается еще куча каких-то реально нужных вычислений с double-точностью, тогда другое дело, тогда этой общий прокол с подключением DirectX и с этим нужно что-то делать. А если ради одной цифирьки в логе, то самое разумное просто добавить в GetElapsedSeconds несколько строчек для проверки, переустановки и восстановления значения MCW_PC
                            leo, ты снова нечётко формулируешь мысли. Твой ответ отвечает не на тот вопрос, который задан. Я бы не стал категорично утверждать, что FPU программе jur-а ограничивается исключительно вычислением циферки для лога. Учитывая формулировку вопроса, jur желает оставить для себя FPU.
                            jur, если есть возможность не использовать FPU вообще, имеет смысл посмотрить в сторону предложения leo.
                            Сообщение отредактировано: Qraizer -
                              Не помню, говорил-ли я о решаемых мною задачах. Прошу меня простить, если уже говорил, а теперь повторяюсь.

                              Я работаю электронщиком-программистом, разрабатываю ультразвуковые медицинские сканеры (УЗИ). В нашем приборе установлена PC-совместимая материнка с Win XP, на которой и крутится приборная программа. В последнее время возникла необходимость освоить еще и не-Интеловскую платформу: довольно крутой DSP от фирмы TI, семейство OMAP. Хорош он тем, что имеет на кристалле два процессора (ARM для задач общего назначения и DSP для наших алгоритмов обработки сигнала) плюс графический ускоритель с отличной производительностью. Все это дело оснащено Windows CE 6.0, которую я постепенно осваиваю. Про Линукс - не говорите, не катит по множеству причин (главная - нулевой опыт применения).

                              Отображение УЗ-картинки осуществляется с помощью DirectX. Выбор этой графической библиотеки обусловлен рядом стародавних причин, многие из которых уже утратили актуальность. (Например, почти 2.5 кратная разница в скорости между DirectX и OpenGL.) Поэтому, а также из-за новой аппаратной платформы, я в ближайшее время полностью перейду на OpenGL. Надеюсь, что там моего вопроса вообще не возникнет.

                              Что касается математики, то в приборах без DSP довольно серьезные вычисления возлагаются на CPU со-товарищи. Поэтому мне важна точность сопроцессора (не фатально, но важно). А раз так, то я, конечно, попробую D3DCREATE_FPU_PRESERVE. Спасибо уважаемый Qraizer!

                              Ну вот примерно так, коротенько... :-)
                                Не могу назвать себя специалистом в OpenGL, но там тип float вроде бы обычное дело в отличие от double.
                                К слову, ARMы очень хорошо следуют IEEE-754.
                                0 пользователей читают эту тему (0 гостей и 0 скрытых пользователей)
                                0 пользователей:
                                Страницы: (3) 1 [2] 3  все


                                Рейтинг@Mail.ru
                                [ Script execution time: 0,0443 ]   [ 16 queries used ]   [ Generated: 10.05.24, 18:52 GMT ]