Распараллеливание растеризации
От: Аноним  
Дата: 12.11.07 13:52
Оценка:
Я тут на днях занялся распараллеливанием своей софтины, которая занимается растеризацией очень большого векторного файла.

Работаю я в MS VS 2005, использую openmp, который как известно этой студией поддерживается…. Тестирую на двух 2-ядерных процах: AMD и Intel.
Схема распараллеливаемого кода:
For (i)
            PrepareToDraw(i)
For (j)
            Draw(j)


Первый for — занимает в среднем 30% времени при последовательном выполнении.


Пробовал я распараллеливать софт 3мя способами:


1) for (i) Draw(i). Где Draw – это куча функций, которые сводятся в итоге к вызову Polyline(hdc, points(i)), где Polyline – это GDI-ный Polyline.
Я поставил #pragma omp parallel for, на Draw поставил критическую секцию (т.к. обращение к GDI + общий dc). Выигрыша не было никакого. Поразмыслив, я решил, что этого стоило ожидать, т.к. 90% времени тратится внутри самой GDi-функции, она непараллельна – ну и результата нет.
2) Я завёл 2 секции соответственно (#pragma omp parallel sections) для двух for соответственно. Конечно, вторая секция зависит от первой, имеет место некая конвеерность. Побился над синхронизацией и… получил совершенно мизерный выигрыш (около 2%). Странно, подумал я.
3) Тогда я распараллелил 1й блок – подготовка к рисованию. Этот блок тоже представляет собой for (i), где i меняется от 1 до 10-100 тысяч. Тело цикла – весьма затратный метод с выполнением разных вычислений и заполнений некоего массива. Шаги друг от друга не зависят. Поставил parallel for – выигрыш был порядка 1-2%. Ужас.

Я пробовал разное число потоков (от 2х и более), пробовал запрещать вложение (omp_set_nested) , без результата.

Отсюда у меня возникло 2 вопроса;



a) Поразмышляв над первым результатом — я подумал, а неужели распараллеливание GDI растеризации вообще невозможно? Неужели никто никогда не пробовал это сделать?
b) Поразмышляв над последними 2 результатами я заподозрил неладное. Тем более слышал страшные рассказы, что по Windows добиться прироста от 2х ядерного проца удаётся только на 10% (против 100% на Linux). Неужели в этом есть доля правды? Может есть какие-то трюки, заставляющие реально распараллеливать алгоритм под Windows?

p.s. Честно говоря, на amd процессоре у меня средняя загрузка проца около 20% — хотя там нет операций ввода-вывода — просто рекурсивные for с заполнением индексных массивов и пересчётом координат. Непонятно во-первых, почему такая маленькая загрузка. Ну и во-вторых, означает ли это, что в силу малой загруженности проца, добавление 2го потока на 2 ядре ничего не принесёт?


Вот и всё собственно,

Заранее благодарю!
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.