Страница: 1 | 2 | 3 |
Вопрос: Параллельный ParallelBitmap
Добавлено: 25.02.11 21:04
Автор вопроса: VβÐUηìt | Web-сайт:
Есть такое? Ну чтобы
using (var g = Graphics.FromImage(bitmap))
Parallel.For(0, 10, i=>
{
g.DrawString(0, i * 10, "Жрать");
});
в смысле если нет, то придется делать вручную его и все методы Graphics для параллельного режима, а это так скушно... Так что хотелось бы, чтобы кто-то уже раз столкнувшийся с этой проблемой запилил кошерный класс.
Суть такова: обычный Bitmap не позволяет работать с собой в многопоточном режиме. Нужен класс, который это делать позволяет, то есть битмап с многопоточным доступом. Если чувак делает какой-нибудь маразм, а-ля из 20 потоков рисует в одном и том же месте, то это его проблемы (на деле все сводится к изменению цветовых компонент, которое само по себе атомарно). То есть, скажем метод DrawString сначала рисует на своем буфере, а затем копирует в указанное место, даже если перехлествается с другим потоком.
Заранее благодарен.
Ответы
Всего ответов: 38
Номер ответа: 1
Автор ответа:
AgentFire
ICQ: 192496851
Вопросов: 75
Ответов: 3178
Профиль | | #1
Добавлено: 25.02.11 23:30
попробуй сделать наследника от Bitmap и, повторяя все его члены, в необходимых местах пиши lock (_syncRoot) {} . возможно прокатит.
Номер ответа: 2
Автор ответа:
EROS
Вопросов: 58
Ответов: 4255
Профиль | | #2
Добавлено: 25.02.11 23:52
А давно это битмап наследоваться начал?
Номер ответа: 3
Автор ответа:
EROS
Вопросов: 58
Ответов: 4255
Профиль | | #3
Добавлено: 25.02.11 23:54
предназначен для распреления задачи по ядрам процессора и к многопоточности отношения не имеет.. То? что тебе надо? делается 1 строкой из Invoke/BeginInvoke// можешь завернуть в свой метод
Номер ответа: 4
Автор ответа:
VβÐUηìt
Вопросов: 246
Ответов: 3333
Web-сайт:
Профиль | | #4
Добавлено: 26.02.11 00:30
Мне не нужно, чтобы он делал Lock. Мне нужно, чтобы несколько отдельных потоков/ядер/срать могли в разных местах одновременно на нем рисовать. Производительность. Если я буду делать Lock, то прироста никакого это не даст. Ибо из WPF нормально копировать отрендеренный видеокартой красивый результат копировать научился только лютым хаком. Вот. Поэтому приходится процессором. А раз процессором, то почему за перерисовку может отвечать максимум 1 ядро? Тогда уж все. Распиливать битмап пополам для двух ядер и рисовать отдельно не предлагать - рисоваться может запросто что-то, что находится в обоих частях. Например текст.
Номер ответа: 5
Автор ответа:
EROS
Вопросов: 58
Ответов: 4255
Профиль | | #5
Добавлено: 26.02.11 01:54
Ну наверное потому,что GDI разрабатывался стопиццот лет назад,когда про многоядерные процессоры еще и не мечтали. Имхо,нифига у тебя не выйдет.. Graphics не допустит одновременного доступа из разных потоков и без lock тебе по любому не обойтись.. И это ограничение не НЕТ а именно GDI
Номер ответа: 6
Автор ответа:
VβÐUηìt
Вопросов: 246
Ответов: 3333
Web-сайт:
Профиль | | #6
Добавлено: 26.02.11 05:58
Далее создаю копии всех функций Graphics. Каждая функция рисует ботву на собственном битмапе в отдельном потоке, а затем копированием декималом по 96 бит сливает в массив. В массив сливать можно параллельно, так что пофиг. Если при этом еще продумать, чтобы для каждой операции не выделялся каждый раз новый битмап, то все вообще было круто. Сделать это можно так: создаем массив из стольких битмапов, сколько есть на компе. Все размером с сам ParallelBitmap. Каждая операция берет свободный битмап и рисует на нем, копиурет результат в основной, затем ложит битмап обратно. Если в данный момент свободных битмапов нет, ждет, пока они появятся. Бо?
Номер ответа: 7
Автор ответа:
VβÐUηìt
Вопросов: 246
Ответов: 3333
Web-сайт:
Профиль | | #7
Добавлено: 26.02.11 05:59
Сделать это можно так: создаем массив из стольких битмапов, сколько есть на компе.
*сколько есть на компе ядер))
Номер ответа: 8
Автор ответа:
AWP
ICQ: 345685652
Вопросов: 96
Ответов: 1212
Web-сайт:
Профиль | | #8
Добавлено: 26.02.11 08:58
Ну с массивом из разных потоков я работал, вроде не вылетало.
Потом можно
SetDIBitsToDevice
или
SetDIBits
Но я так понимаю, что тебе видеокартой нужно?
Номер ответа: 9
Автор ответа:
VβÐUηìt
Вопросов: 246
Ответов: 3333
Web-сайт:
Профиль | | #9
Добавлено: 26.02.11 13:23
Раньше нужно было. Но там другая история - тупо рисуем все в WPF видеокартой, а потом забирать от туда. RenderTargetBitmap рисует все процессором, и производительность ужасна. Поэтому решил вернуться к GDI, который тоже медленный Но его можно распараллелить, то есть использовать для прорисовки все ядра процессора, а не одно. Тогда получается более-менее нормально.
Я хочу запилить примерно это:
То есть спокойно параллельно рисуем все прямо на битмапе разными ядрами. Или потоками - не суть. И никаких "другой поток использует Bitmap". В данном примере это особой роли в производительности не даст, но там, где это поланируется использовать, прирост должен быть существенным.
Функции ParallelBitmap, которые используют Windows API, рисуют свое дело на отдельных битмапах в своем потоке, затем в нем же переносят в 2D-массив цветов.
Функции, которые не требуют WindowsAPI (например, DrawImage - можно спокойно самому написать побайтовое (или по 4 байта для 32x) копирование), рисуют все прямо сразу по массиву, не используя других битмапов и экономя ресурсы на копировании. Бо?
Номер ответа: 10
Автор ответа:
AgentFire
ICQ: 192496851
Вопросов: 75
Ответов: 3178
Профиль | | #10
Добавлено: 26.02.11 14:32
бо-то бо, а ты пробуй и делай бенчмарки
Номер ответа: 11
Автор ответа:
EROS
Вопросов: 58
Ответов: 4255
Профиль | | #11
Добавлено: 27.02.11 12:09
в таком случае Scan0 + unsafe тебе в помощь
Номер ответа: 12
Автор ответа:
VβÐUηìt
Вопросов: 246
Ответов: 3333
Web-сайт:
Профиль | | #12
Добавлено: 27.02.11 13:21
Мне тут сказали, что оказывается можно создать несколько битмапов на одной и той же памяти. То есть битмапов какбэ, скажем, два, но память у них одна. Как это запилить?
Номер ответа: 13
Автор ответа:
AgentFire
ICQ: 192496851
Вопросов: 75
Ответов: 3178
Профиль | | #13
Добавлено: 27.02.11 18:19
CopyMemory как вариант?
Номер ответа: 14
Автор ответа:
VβÐUηìt
Вопросов: 246
Ответов: 3333
Web-сайт:
Профиль | | #14
Добавлено: 27.02.11 22:22
Нееет. Нужно чтобы было два класса Bitmap, которые ссылаются на один и тот же кусок памяти. Чтобы лохануть WinAPI. Народ говорил, что работает. То есть мы из двух потоков рисуем на разных битмапах, но на деле работаем с одним куском памяти. Без копирований.
Номер ответа: 15
Автор ответа:
EROS
Вопросов: 58
Ответов: 4255
Профиль | | #15
Добавлено: 28.02.11 02:07
Так спроси у того,кто такое сказал. Я даже не догоняю что имелось ввиду.. как у 2 разных объектов может быть одна память??? имхо, бред..