Вопрос о BltFast

Тема в разделе "WASM.DirectX", создана пользователем inew, 14 дек 2004.

  1. inew

    inew New Member

    Публикаций:
    0
    Регистрация:
    30 ноя 2004
    Сообщения:
    26
    Подскажите, кто знает..

    BltFast при выводе на первичную поверхность не синхронизируется с обратным вертикальным ходом луча?



    Я замерил время выполнения проги с переключением Flip и точно такой же проги, но в которой вместо Flip стоит BltFast из бэка на первичную поверхность. В результате выяснилось, что второй вариант в 3.8 раза быстрее первого. К тому же разброс времени выполнения у второго варианта состовляет +0.7% -0.6%, а у первого он +33% -25%.



    Отсюда предположение: это потому, что Flip ждет обратного хода, а BltFast нет?
     
  2. S_T_A_S_

    S_T_A_S_ New Member

    Публикаций:
    0
    Регистрация:
    27 окт 2003
    Сообщения:
    1.754
    Не синхронизируется. Метод в общем расчитан на вывод спрайтов, представь, если для каждого спрайта будет ждать VSync :)

    Для Flip можно указать флаг DDFLIP_NOVSYNC:







    Для синхронизации можно использовать отдельно IDirectDraw::WaitForVerticalBlank



    У тя похоже доки нет? MSDN тут мало помогает, там 8й и 9й только. Те лучше всего DX7SDK найти. Могу отправить ddraw.doc по 6.1 или 7. chm щас врядли потяну, инет еле работает :-(
     
  3. inew

    inew New Member

    Публикаций:
    0
    Регистрация:
    30 ноя 2004
    Сообщения:
    26
    S_T_A_S_



    Ты понимаешь, попробовал изменить коренным образом прогу kublo.asm (та, которая точки движущиеся выводит), а именно - сделать двухпоточной, как всякое подергивание анимации исчезло!

    При этом один поток (основной) создает при инициализации проги вторичный поток (который занимается только рендерингом), дает ему приоритет REALTIME и запускает.

    А сам обрабатывает только сообщения от основного окна и сообщения от вторичного потока. К тому же, основной поток вызывает не PeekMeesage, а GetMessage (чтобы разгрузить Винду, пока нет для него сообщений).

    В таком варианте вроде бы все ОК, да не все.

    Начал тестировать 2 варианта программы (однопоточную и двухпоточную) на разных системах и под разными Виндами.

    Метод тестирования один и тот же - замеряется количество тиков ЦПУ между концом отрисовки предыдущего кадра и концом отрисовки текущего кадра за вычетом времени на искусственную синхронизацию через Sleep. Данное "чистое" время отрисовки одного кадра с учетом взаимодействия с Виндой суммируется в течение 2000 кадров анимации. После этого прога заканчивает работу и выводит общую сумму затраченных тиков.

    Я сравниваю отношение средних показаний временнЫх затрат однопоточного варианта и двухпоточного варианта для определения, какой же метод все таки лучше. Но в результате на разных ПК получаю разные отношения. В большинстве случаев (как правило, на Вин98 и Вин2000) многопоточный вариант быстрее однопоточного, но в некоторых случая (как правило, на ВинХР) наоборот. И при том существеннее многопоточный вариант медленнее однопоточного.

    Может быть, думаю, это происходит оттого, что я не смог корректно показать Винде, что мой поток - важнее других. Или еще какие-то причины.



    ЗЫ Честно говоря, мне многопоточный вариант нравится больше, чем однопоточный. Чувствую, что это должно быть ближе к технике Винды. Но как заставить его во всех случаях быть быстрее?
     
  4. S_T_A_S_

    S_T_A_S_ New Member

    Публикаций:
    0
    Регистрация:
    27 окт 2003
    Сообщения:
    1.754
    К технике виндоса это конечно ближе, но сама идеология виндоса плохо стыкуется с игрушками. Так, XBox использует ядро от 2К, но там существует всего один процесс..



    Вообще, в инете я часто встречал инфу, что многопоточность в DX вызывает снижение производительности. В отдельном потоке делают музыку, физику, но не рендеринг. Да у тя, похоже, так и есть - "основной" поток с REALTIME всё рисует, а "вспомогательный" всего-то обрабатывает мессаги :). Хотя IMHO лучше использование сообщений сводить к минимуму: WM_ACTIVATE, WM_DESTROY, ну может ещё WM_CREATE. Вообще, не совсем понятно, зачем разделять это на 2 потока, у меня, на пример, kublo.exe без проблем работало (может из-за компа - AXP2000+/512/Radeon8500 XPSP2)



    >




    Что-то не пойму, что меряешь. Если нужно время отрисовки - то это разница между началом и концом рендеринга, кадры тут причём? В идеале, кадры должны меняться с частотой развёртки - больше делать _нет_ смысла, а меньше - графика будет репаться. Сколько времени при этом уходит на отрисовку, по сути, не важно. К сожалению на PC это сложно реализовать, т.к. развёртка сильно отличаться может, поэтому-то зачастую в Спектрумовских игрушках на телевизоре всё куда плавнее движется, чем на современных монстрах :-(
     
  5. Narkomanius

    Narkomanius New Member

    Публикаций:
    0
    Регистрация:
    14 апр 2003
    Сообщения:
    144
    флип быстрее потому что память не копируется!!!!

    видяха умеет переключатьадрес фрамебуфера апоратно
     
  6. inew

    inew New Member

    Публикаций:
    0
    Регистрация:
    30 ноя 2004
    Сообщения:
    26
    S_T_A_S_

    Наверное, я слишком запутанно изложил метод замера времени. В принципе, он сводится, как ты и сказал, к разнице между началом и концом рендеринга.

    См. алгоритм тела потока REALTIME, который осуществляет рендеринг:



    Начало:

    1. извлечь кол-во тиков на данный момент и сохранить как Т(QueryPerformanceCounter)

    2. Общая сумма тиков С=0

    Начало цикла:

    0. Проверить, есть ли команда сверху закрыть поток, если да, перейти на конец потока

    1. Отрисовать кадр

    2. извлечь кол-во тиков на данный момент как Н

    3. найти разницу Н-Т и добавить ее к С

    4. посчитать, сколько надо СПАТЬ, чтобы обеспечить 20 кадров в секунду

    5. Sleep на указанное время

    6. извлечь кол-во тиков на данный момент и сохранить как Т

    7. перейти на начало цикла

    конец потока:

    1. Отправить наверх SendMessage WM_END_THREAD и закончить поток ret



    Т.о. я считаю время между двумя кадрами, но не учитывая время на Sleep
     
  7. S_T_A_S_

    S_T_A_S_ New Member

    Публикаций:
    0
    Регистрация:
    27 окт 2003
    Сообщения:
    1.754
    Narkomanius >




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





    inew >




    Ну ты попробуй в однопоточном варианте дать приоритет REALTIME и посмотри, что получится ;)
     
  8. inew

    inew New Member

    Публикаций:
    0
    Регистрация:
    30 ноя 2004
    Сообщения:
    26
    S_T_A_S_

    Кстати, вопросик по приоритетам. Для своего дувхпоточного примера я из основного (родительского) треда создаю второй поток, далее устанавливаю ему макс. приоритет SetPriorityThread = THREAD_PRIORITY_CRITICAL_TIME.

    В этом-то треде как раз и осуществляется рендеринг.

    Сам процесс же имеет приоритет NORMAL (как обычный юзерский процесс по умолчанию).

    Комбинация NORMAL + THREAD_PRIORITY_CRITICAL_TIME дает согласно SDK общий приоритет = 15.

    Я хочу попробовать поднять приоритет процесса до HIGH или даже REALTIME, чтобы в комбинации с THREAD_PRIORITY_CRITICAL_TIME общий приоритет был повыше.

    Установить приоритет можно SetPriorityClass, но он требует хендл процесса.

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



    ЗЫ Видел GetCurrentProcess, но в SDK сказано, что он возвращает ПСЕВДОХЕНДЛ. Это что такое, то же самое, что и ХЕНДЛ?



    И просьба на счет ddraw.doc по 7.0, если не затруднит, пож-ста... inew@mail.ru
     
  9. Turkish

    Turkish New Member

    Публикаций:
    0
    Регистрация:
    25 окт 2004
    Сообщения:
    80
    Адрес:
    Russia
    Именно GetCurrentProcess тебе нужен
     
  10. S_T_A_S_

    S_T_A_S_ New Member

    Публикаций:
    0
    Регистрация:
    27 окт 2003
    Сообщения:
    1.754
    inew



    Вообще, ты много игрушек видел, которые себе приоритет делают REALTIME? Я что-то не помню таких..



    ЗЫ: отправил, проверяй мыло