Перейти к содержанию

kaktus

Стажёры
  • Публикаций

    8
  • Зарегистрирован

  • Посещение

Репутация

1 Навыки не прокачены

Информация о kaktus

  • Звание
    Новичок
  1. Ты предложил - и я услышал. Тестирование DIB секций я начал с твоей подачи. Тебе большое человеческое спасибо.
  2. Ура - DIB работает !!! И все странности со временем выполнения пропали. Скорость отрисовки тоже повысилась. 1 столбец - 10мсек. 2 столбца 14 мсек. Я так-же очень доволен тем фактом что нужные мне графические функции API типа TextOut поддерживают полноценную работу с DIB. Так-же приятный бонус, что теперь можно писать напрямую в массив памяти и несомненно это будет быстрее чем SetPixel (.... не выдержал, проверил - 2 мсек. Более чем 10и кратное ускорение, если учитывать накладные расходы на обслуживание потоков..) Предварительные выводы - 1.CreateCompatibleBitmap создаёт BITMAP привязанный к дайверу видеокарты (возможно к памяти видеокарты) 2. Параллелить вывод (если позволяет логика приложения) можно используя DIB секции. А судя по странностям с задержками вывода на основной DC так вообще предпочтительнее выводить сначала в DIB а потом BitBlt в основной DC. Всё равно народ в основном через двойной буфер выводит, так и пусть этот буфер будет DIB типа. 3. DIB секции поддерживают графические операции API и прямой доступ к плоскости изображения и скорее всего поддерживают все графические функции API (например кривые Безье) 4. Я маньяк (волосы торчат, глаза красные - пора спать) Если какие вопросы будут - пишите в ветку, спрашивайте. Я ещё какое-то время сюда буду заходить на всякий случай.
  3. Хм... Всё страньше и страньше ... Напоминаю - программа заполняет две области 400x100 случайными пикселями. Мучая несчастный GDI заметил такую странность. (Я сейчас исключительно про однопоточный режим. Вся работа происходит в основном потоке программы). Время работы программы меняется непредсказуемым образом, но принимает всего три значения - 32 мсек. 86мсек и 130мсек. ну плюс/минус конечно. Измеритель у меня точный - QueryPerfomanceCounter, не какой-нибудь там GetTickCount . Комп не занят, 4ре ядра... Ещё страньше то, что API SetPixel выполняется дольше чем Canvas.SetPixels[x,y] Хотя Canvas.SetPixels обёртка вокруг API SetPixel. Чудеса вобщем. Ну да ладно - это чисто теоретический интерес, пока отложим. Приятная новость заключается в том, что под Win7 время заполнения на нескольких потоках по крайней мере не больше чем на одном потоке. Уже радует. Ложка дёгтя тут заключается в том, что есть некая технологическая программа, которая работает исключительно на winXP (HASP, там ... все дела). И на таких компах ускорения отрисовки не получится. Хотя возможно и Windows7 не взлетит, проверю - напишу результат. Далее по плану помучать DIBsection. Есть подозрение что CompatibleDC это всё таки про видеокарту и соответственно не shared ресурс, а DIB это про ОЗУ и возможно windows не будет разделять доступ к таким ресурсам. ps: Если я пишу где-то глупость, то не стесняйтесь поправляйте меня. Я полез Куда Макар телят не гонял в несвойственные мне дебри и естественно буду косячить,
  4. Да это вобщем-то неважно, речь идёт о том что параллельная работа с GDI невозможна. Не нравится SetPixel - попробуй TextOut раз 500 на поток. Окажется что в однопотоке это всё выполняется быстрее чем в многопотоке. А если попытаться проследить выполнение кода - окажется, что потоки встают в очередь и выполняются последовательно. - Угу, я тоже так думал. Попробуй на C++ это сотворить - сильно удивишся. Блокировка идёт не на уровне bitmap (я про тот который HBITMAP потому что tBimap считается потокобезопасным, а значит однозначно набит Locka-ами/UnLock-ами ) и блокировка идёт даже не на уровне bitmap а скорее либо на уровне драйвера видеокарты (и CompatibleDC тут не спасает) либо сама Windows не позволяет выполнять графические функции API в нескольких потоках. Та там практически чистый API. Всякие удобные обёртки типа tThread к проблеме отношения не имеют. Посмотри код который я приложил - он хорошо документирован. Попробуй его выполнить на C++ тогда поймёшь масштаб беды Я конечно могу на С++ пример приложить, но на это уйдёт крайне много времени т.к. мне придётся начинать с установки среды программирования. И программу на C++ мне придётся писать чуть ли не с букварём. Я надеюсь что на форуме есть люди которые умеют и C++ и ObjectPascal.
  5. Про SendMessage в SetPixel я конечно погорячился но мне простительно, это я от отчаяния. (Что конечно не отрицает возможности наличия других типов блокировок в графических функциях GDI) Привожу максимально упрощённый код для тестирования многопоточной отрисовки. К качеству прошу не придираться - код для демонстрации. https://fex.net/ru/s/lxdcmrp не смог найти как прикрепить файл к форуму, через некоторое время ссылка протухнет и для потомков ничего не останется. ps: С++ я тоже понимаю со словарём Поэтому если кто-нибудь решится привести рабочий пример многопоточной отрисовки на C++ это тоже будет считаться благородным поступком и зачтётся плюсиком в карму.
  6. Я так делал : Создавал несколько CompatibleDC/Compatible bitmap в основном потоке и отпускал DC. Затем запускал потоки и после их завершения освобождал Compatible ресурсы. Увы - тоже не взлетело. А как прикрепить файл - rar архив,? Я не нашёл. ps: Мне почему то кажется, что сама операция SetPixel содержит код который включает механизм блокировки, (например SetPixel вызывает SendMessage) я в гугле нашёл множество аналогичных вопросов на эту проблему, но не нашёл ни одного решения - кроме отсылок к msdn и уверений, что это возможно "мамой клянусь". Я больше склоняюсь к мысли что это невозможно и придётся работать с массивами и низкоуровневыми алгоритмами отрисовки.
  7. Я так и делал, вот код потока Это было для проверки времени выполнения и до вывода результата даже не дошло. Если закомментить SetPixel - то блокировок не возникает на любом количестве потоков. Однако любая графическая операция тут же начинает блокировать поток. Потоки начинают выполнятся последовательно. Я даже делал так - создавал и удалял CompatibleDC в основном потоке (использовал массив) а потокам раздавал уже готовый bitmap ( думал что может GetDC блокировало) - но нет, не помогло.
  8. Thread(N).Bitmap.Canvas.Pixels[x,y] наверняка лочится, однако я отрабатывал множество разных вариантов, в том числе и вариант API SetPixel(DC,X,Y,Color) - увы он тоже лочит потоки.
  9. Здравствуйте. Кто может подсказать по поводу многопоточной отрисовки графики посредством GDI ? Суть в следующем - экран разбит на 5 столбцов шириной примерно 200 пикселей. В каждый столбец рисую несколько графиков используя Canvas.Pixels либо Canvas.MoveTo,LineTo. С целью ускорения вывода сделал отрисовку каждого столбца в своём потоке, а после отрисовки всех столбцов многопоточно,далее в основном потоке делаю вывод на экран посредством Canvas.Draw. Для каждого столбца создаётся своя bitmap на собственном CompatibleDC.Однако скорость не увеличивается, а наоборот уменьшается и довольно сильно. Путём отладки выяснил, что в момент выполнения Canvas.Pixels поток лочится и другие потоки не работают. Ещё раз повторю для каждого потока создаётся собственная bitmap привязанная к совственному CompatibleDC. т.е. при выполнении Thread(N).Bitmap.Canvas.Pixels[x,y] := RandomColor все остальные Thread лочатся до завершения операции в Thread(N). И не просто до завершения, а лок висит ещё довольно долго, что приводит к увеличению времени отрисовки по срвнению с однопоточным режимом. Реальные цифры таковы в однопоточном режиме заполнение одного столбца 400X100 случайными пикселями происходит примерно за 16 мсек. Двух столбцов 32 мсек. В многопоточном режиме - один столбец,один поток (блокировок потоков не возникает) 16мсек. два столбца, два потока 210 мсек. (чем больше столбцов тем дольше рисует по сравнению с однопотоком) выход пока видится только в создании массивов плоскостей пикселей не привязанных ни к какому DC и отрисовка на этих плоскостях графических примитивой с помощью например алгоритмов Брезенхема. Но хотелось бы DrawText со всем шрифтовым богатством Windows. Вопрос в следующем - рисовал ли кто в многопотоке функциями GDI и каким образм ? ps: WinXp / Delphi7
×
×
  • Создать...

Важная информация

Находясь на нашем сайте, Вы автоматически соглашаетесь соблюдать наши Условия использования.