Форум: "Основная";
Текущий архив: 2007.08.19;
Скачать: [xml.tar.bz2];
ВнизОбработка Bitmap двумя Thread Найти похожие ветки
← →
Igor_K_A (2007-06-07 05:21) [0]Помогите решить проблему: есть Bitmap определенный в главном потоке программы и два дополнительных потока TThread, которые должны обрабатывать битмап парраллельно. Оброботка заключается в простом уменьшении разрешения - картинка бьется на ячейки, в каждой определяется доминирующий цвет и на сжатой картинке исходная картинка представляется уже одним пикселом. Замечен следующий баг: иногда выходная картинка закрашивается черным цветом на произвольную величину..а после этого выпадает "out of system resources". если использовать
MyThread1.Resume;
MyThread1.WaitFor;
MyThread2.Resume;
MyThread2.WaitFor;
вид запуска то все работает без ошибок и глюков, но теряется параллелизм :(
← →
ЮЮ © (2007-06-07 08:03) [1]Чисто интереса ради, какого размера твой Bitmap, что для такого элементарного, по сути, преобразования потребовальсь доп.потоки, да ещё два?
← →
oxffff © (2007-06-07 09:00) [2]
> ЮЮ © (07.06.07 08:03) [1]
> Чисто интереса ради, какого размера твой Bitmap, что для
> такого элементарного, по сути, преобразования потребовальсь
> доп.потоки, да ещё два?
Многоядерность?
← →
homm © (2007-06-07 13:59) [3]> Многоядерность?
Шишь он получит увеличение производительности на опирации интенсивной работы с памятью. Только если у него кривой алгоритм, излишне нагружающий процессор. Но в этом случае действуют не распаралеливанием, а улучшением алгоритма.
← →
oxffff © (2007-06-07 14:36) [4]
> homm © (07.06.07 13:59) [3]
> > Многоядерность?
>
> Шишь он получит увеличение производительности на опирации
> интенсивной работы с памятью. Только если у него кривой
> алгоритм, излишне нагружающий процессор. Но в этом случае
> действуют не распаралеливанием, а улучшением алгоритма.
Поясни свой ответ
← →
homm © (2007-06-07 14:40) [5]> Поясни свой ответ
Мда… :)
Распаралеливать нужно только когда все остальные способы увеличения производительности испробованы. К чему разносить на другой проц код, который делает лишнюю работу?
← →
oxffff © (2007-06-07 15:02) [6]
> homm © (07.06.07 14:40) [5]
> > Поясни свой ответ
>
> Мда… :)
>
> Распаралеливать нужно только когда все остальные способы
> увеличения производительности испробованы. К чему разносить
> на другой проц код, который делает лишнюю работу?
>Шишь он получит увеличение производительности на опирации
>интенсивной работы с памятью.
Не соозволите ли доказать сие свое утверждение?
← →
oxffff © (2007-06-07 15:12) [7]Tо homm
1. Читай про тенденции процессоростроения к многоядерность
2. Читать про кэш память
3. Думать перед ответом.
4. Не засорять форум. ;)
← →
oxffff © (2007-06-07 15:13) [8]Кэш-память
Кэш-память представляет собой быстродействующее ЗУ, размещенное на одном кристалле с ЦП или внешнее по отношению к ЦП. Кэш служит высокоскоростным буфером между ЦП и относительно медленной основной памятью. Идея кэш-памяти основана на прогнозировании наиболее вероятных обращений ЦП к оперативной памяти. В основу такого подхода положен принцип временной и пространственной локальности программы.
Если ЦП обратился к какому-либо объекту оперативной памяти, с высокой долей вероятности ЦП вскоре снова обратится к этому объекту. Примером этой ситуации может быть код или данные в циклах. Эта концепция описывается принципом временной локальности, в соответствии с которым часто используемые объекты оперативной памяти должны быть "ближе" к ЦП (в кэше).
Для согласования содержимого кэш-памяти и оперативной памяти используют три метода записи:
Сквозная запись (write through) - одновременно с кэш-памятью обновляется оперативная память.
Буферизованная сквозная запись (buffered write through) - информация задерживается в кэш-буфере перед записью в оперативную память и переписывается в оперативную память в те циклы, когда ЦП к ней не обращается.
Обратная запись (write back) - используется бит изменения в поле тега, и строка переписывается в оперативную память только в том случае, если бит изменения равен 1.
Как правило, все методы записи, кроме сквозной, позволяют для увеличения производительности откладывать и группировать операции записи в оперативную память.
← →
oxffff © (2007-06-07 15:14) [9]Далее читать про разделяемый кэш и когерентность кэшей.
← →
homm © (2007-06-07 16:11) [10]> 1. Читай про тенденции процессоростроения к многоядерность
Давай я тебе так намекну, без тенденций? Есть догадка, что автор пытается распаралелить процесс потому что он у него жутко торозит. А тормозит потому что Get\SetPixel. Сколько ядер тебе понадобиться, чтобы такой алгоритм работал хотя-бы со скоростью грамотно написаного для одного ядра на ассемблере? 128? 1024? Вперед, за тенденцией, удачи.
← →
oxffff © (2007-06-07 16:17) [11]>Оброботка заключается в простом уменьшении разрешения - картинка >бьется на ячейки, в каждой определяется доминирующий цвет и на сжатой >картинке исходная картинка представляется уже одним пикселом
Внимательно читал?
← →
oxffff © (2007-06-07 16:20) [12]Это уже кандидат на многопоточный алгоритм.
А что там у автора не получается. Не известно.
← →
homm © (2007-06-07 16:20) [13]> Внимательно читал?
Вполне. «каждой определяется доминирующий цвет». Это что по твоему, как не чтение?
← →
oxffff © (2007-06-07 16:22) [14]
> Это что по твоему, как не чтение?
картинка бьется на ячейки и они не связаны.
← →
homm © (2007-06-07 16:30) [15]> картинка бьется на ячейки и они не связаны.
Физически? Логически? Автор придет, тогда поспоришь, любитель пофлудить.
← →
tesseract © (2007-06-07 16:34) [16]
> Физически? Логически?
Если два ядра, то они явно будут разбросаны по памяти процессов/ядер, т.е физически.
← →
oxffff © (2007-06-07 16:36) [17]
> homm © (07.06.07 16:30) [15]
> > картинка бьется на ячейки и они не связаны.
>
> Физически? Логически? Автор придет, тогда поспоришь, любитель
> пофлудить.
И это все что можешь сказать?
тогда читай oxffff © (07.06.07 15:12) [7]
← →
oxffff © (2007-06-07 16:38) [18]
> tesseract © (07.06.07 16:34) [16]
>
> > Физически? Логически?
>
>
> Если два ядра, то они явно будут разбросаны по памяти процессов/ядер,
> т.е физически.
Это к чему?
← →
Igor_K_A (2007-06-07 16:58) [19]Ядра действительно два. Картинка бьется пополам и каждая половинка обрабатывается независимо. т.е. нет информационных зависимостей. Картинка большая. Необходим именно параллелизм..т.к. это тема на диплом :)) "распараллеливание больших задач"
← →
Сергей М. © (2007-06-07 17:03) [20]
> Картинка бьется пополам
Показывай как "бьешь пополам" ...
← →
Igor_K_A (2007-06-07 17:10) [21]MyThread1 := TMyThread.Create(true);
MyThread1.bp:=0; //начало интервала обработки
MyThread1.ep:=((Bit.Width div st) div 2)*st; //конец интервала обработки, st шаг сетки
MyThread1.Resume;
MyThread1.WaitFor; //////////
MyThread2 := TMyThread.Create(true);
MyThread2.bp:=((Bit.Width div st) div 2)*st+1;
MyThread2.ep:=Bit.Width;
MyThread2.Resume;
MyThread2.WaitFor; //////////
В таком виде работает все ок, но последовательно... если закоментировать строки помеченные ////////// тогда и начинаются все проблемы....причем даже если порождать один процесс то те же глюки
← →
MBo © (2007-06-07 18:14) [22]ты до сих пор не сказал, как к битмапу обращаешься
← →
homm © (2007-06-07 18:24) [23]Разбивай по ширине, а не по высоте на 2 части. В том коде, который ты привел вообще не понятно на что ты разбиваешь.
← →
homm © (2007-06-07 18:25) [24]> Разбивай по ширине, а не по высоте на 2 части.
Наоборот :)
← →
Igor_K_A (2007-06-07 18:27) [25]procedure TMyThread.Execute;
begin
........
BitOut.Canvas.Pixels[i div st,j div st]:=GetColorSubMap(i,j,st);// BitOut Bitmap для хранения сжатой картинки, тоже определен в главном потоке программы
........
function TMyThread.GetColorSubMap(x,y,step: integer):TColor;
var
i,j,k: integer;
max: integer;
begin
dec(step);
max:=0;
for i:=x to x+step do
for j:=y to y+step do
begin
if not(VL.FindRow(ColorToString(Bit.Canvas.Pixels[i,j]),k)) then
VL.InsertRow(ColorToString(Bit.Canvas.Pixels[i,j]),"1",true)
else
VL.Cells[1,k]:=IntToStr(StrToInt(VL.Cells[1,k])+1);
end;
k:=0;
for i:=1 to VL.RowCount-1 do
begin
if StrToInt(VL.Cells[1,i])>max then begin max:=StrToInt(VL.Cells[1,i]); k:=i; end;
end;
Result:=StringToColor(VL.Cells[0,k]);
VL.Strings.Clear;
end;
end;
← →
homm © (2007-06-07 18:35) [26]Мама дорогая. А потом этот «дипломник» будет разрабатывать программы для видеонаблюдения в аэропортах, от которых в какой-то степени будет зависеть моя жизнь. Помоему справедливо бкдет помочь только в том случае, если он пообкщает пойти торговать сотовыми телефонами, и больше не прикасатся к компилятору.
2 oxffff
Что я говорил? Как тебе код? Считаешь, все еше считаешь что то что здесь нужно — распаралелить на 2 ядра?
← →
MBo © (2007-06-07 18:41) [27]крайне неразумно озадачиваться каким-то распараллеливанием, пока столько исключительно медленных операций даже в одной строке:
VL.FindRow(ColorToString(Bit.Canvas.Pixels[i,j]),k))
тем не менее: обращение к Canvas.Pixels не может производиться одновременно из нескольких потоков, нужна синхронизация.
← →
Anatoly Podgoretsky © (2007-06-07 19:42) [28]Что и следовало ожидать, тут не распаралеливать нужно, а веники вязать.
← →
oxffff © (2007-06-07 20:24) [29]
> homm © (07.06.07 18:35) [26]
> Мама дорогая. А потом этот «дипломник» будет разрабатывать
> программы для видеонаблюдения в аэропортах, от которых в
> какой-то степени будет зависеть моя жизнь. Помоему справедливо
> бкдет помочь только в том случае, если он пообкщает пойти
> торговать сотовыми телефонами, и больше не прикасатся к
> компилятору.
>
> 2 oxffff
> Что я говорил? Как тебе код? Считаешь, все еше считаешь
> что то что здесь нужно — распаралелить на 2 ядра?
Я останусь при своем мнении, так же как и ты.
Думаю ты не можешь со мной не согласиться.
И это не потому что не я такой, а это инициатива Intel, Amd, NVidia.
Многоядерность и все.
Поэтому уже сейчас он нас требуют "решать шире вопросы", чтобы производительность хорошо масштабировалась с добавлением "вычислительных ядер", естественно не GUI приложения.
А для задач подобной этой.
Stream processing и все
Другой вопрос это конкретный вопрос автора темы.
Что он хочет неизвестно.
> MBo © (07.06.07 18:41) [27]
> крайне неразумно озадачиваться каким-то распараллеливанием,
> пока столько исключительно медленных операций даже в одной
> строке:
> VL.FindRow(ColorToString(Bit.Canvas.Pixels[i,j]),k))
>
> тем не менее: обращение к Canvas.Pixels не может производиться
> одновременно из нескольких потоков, нужна синхронизация.
>
MBo © (07.06.07 18:41) [27]
Lock buffer eму в помощь
← →
homm © (2007-06-07 20:27) [30]> Я останусь при своем мнении, так же как и ты.
> Думаю ты не можешь со мной не согласиться.
> И это не потому что не я такой, а это инициатива Intel,
> Amd, NVidia.
> Многоядерность и все.
При чем тут многоядерность? Код стмотрел? Ему что, второе ядро поможет? Забудь про коня в вакууме.
← →
oxffff © (2007-06-07 20:39) [31]
> homm © (07.06.07 20:27) [30]
> > Я останусь при своем мнении, так же как и ты.
> > Думаю ты не можешь со мной не согласиться.
> > И это не потому что не я такой, а это инициатива Intel,
>
> > Amd, NVidia.
> > Многоядерность и все.
>
> При чем тут многоядерность? Код стмотрел? Ему что, второе
> ядро поможет? Забудь про коня в вакууме.
Ему пока нет. Но думаю до сдачи сделает. Во всяком случае надеюсь.
← →
homm © (2007-06-07 20:47) [32]> Ему пока нет.
А говорил что при своем мнении останешься :)
← →
oxffff © (2007-06-07 20:50) [33]
> homm © (07.06.07 20:47) [32]
> > Ему пока нет.
>
> А говорил что при своем мнении останешься :)
Как тебе будет угодно. Но замечу мое мнение относилось к задаче, а не варианту решения этой задачи конкретным человеком.
← →
Eraser © (2007-06-07 21:07) [34]> [0] Igor_K_A (07.06.07 05:21)
в многопоточном приложений при обращении к битмапу обязательно нужно использовать bmp.Canvas.Lock/Unlock иначе ошибки и глюки неминуемы.
← →
Igor_K_A (2007-06-07 21:32) [35]Eraser, вы гуру! Мой вам респект! Коротко и ясно! Всем остальным тоже спасибо... алгоритм обязательно оптимизирую и убиру медленные куски
← →
DVM © (2007-06-07 21:53) [36]
> Eraser, вы гуру! Мой вам респект! Коротко и ясно!
Только вот толку от многопоточности не будет никакой ибо пока один поток залочил битмап, другой будет ждать.
← →
homm © (2007-06-07 22:01) [37]> алгоритм обязательно оптимизирую и убиру медленные куски
Тебе не медленные куски убирать надо, а книжки читать и усиленно думать. Возьми для начала библиотеку какую, FastDib или какие еше там бывают. Это ДЛЯ НАЧАЛА. Был бы я на месте преподов, вообще бы оценку не ставил пока на ассемблере с использованием mmx бы не реализовал. Просто интересно, это все задание на диплом? Потому как это даже на 10-ю часть не тянет.
← →
DVM © (2007-06-07 22:06) [38]
> Был бы я на месте преподов, вообще бы оценку не ставил пока
> на ассемблере с использованием mmx бы не реализовал
Как показывает практика можно и без асма сделать не хуже. А то и лучше. Ибо оптимизатор делфи генерит код очень хитро и лучше чем большинство программеров среднего уровня на асме.
> Igor_K_A (07.06.07 18:27) [25]
Код хуже не бывает.
> Bit.Canvas.Pixels[i,j]),
Это чудовищно медленно. Можно написать раз в 100 быстрее работающее.
← →
oxffff © (2007-06-07 22:07) [39]
> Igor_K_A (07.06.07 21:32) [35]
> Eraser, вы гуру! Мой вам респект! Коротко и ясно! Всем остальным
> тоже спасибо... алгоритм обязательно оптимизирую и убиру
> медленные куски
Читать про GetDIBits
← →
homm © (2007-06-07 22:23) [40]> Как показывает практика можно и без асма сделать не хуже.
> А то и лучше. Ибо оптимизатор делфи генерит код очень хитро
> и лучше чем большинство программеров среднего уровня на
> асме.
Приятно знать, что я не «программер среднего уровня» в этом вопросе. Хотя, признать, без использования MMX как-то увеличить скорость грамотного(!) кода достаточно трудно.
← →
Eraser © (2007-06-07 22:26) [41]> [36] DVM © (07.06.07 21:53)
> Только вот толку от многопоточности не будет никакой ибо
> пока один поток залочил битмап, другой будет ждать.
а по-другому никак, GDI функции не потокобезопасны.
а толк будет, при условии, что один поток постоянно работает с битмапом, а другой, к примеру, только время от времени занимается прорисовкой этого битмапа на форме.
← →
homm © (2007-06-07 22:30) [42]> а толк будет, при условии, что один поток постоянно работает
> с битмапом, а другой, к примеру, только время от времени
> занимается прорисовкой этого битмапа на форме.
Можно не использовать GDI функции для обработки. См. [39]
← →
oxffff © (2007-06-07 22:31) [43]
> а по-другому никак, GDI функции не потокобезопасны.
Ему нужно просто выдернуть весь буфер.
Поскольку этот буфер статичен (только чтение, используется как источник), то обращение к нему бы влечет за собой нагрузки на когерентность кэша при многоядерности и многосокетности.
← →
oxffff © (2007-06-07 22:33) [44]
> Поскольку этот буфер статичен (только чтение, используется
> как источник), то обращение к нему НЕ влечет за собой нагрузки
> на когерентность кэша при многоядерности и многосокетности.
>
← →
Eraser © (2007-06-07 23:05) [45]> [43] oxffff © (07.06.07 22:31)
судя по задаче, автору проще создать 2 отдельных битмапа, а после обработки в отдельных потоках просто склеить их..
← →
homm © (2007-06-07 23:14) [46]> [45] Eraser
процедуру склейки не распаралелишь, к тому-же не понятно, чем «проще».
← →
oxffff © (2007-06-07 23:16) [47]Купить?
← →
oxffff © (2007-06-07 23:17) [48]Книгу естественно.
← →
oxffff © (2007-06-07 23:27) [49]to Igor_K_A
Вы нас всех хоть в соавторах диплома упомините.
Хотя больше на практическое задание смахивает.
← →
Eraser © (2007-06-08 00:03) [50]> чем «проще».
чем на свой страх и риск блокировать участки памяти.
← →
homm © (2007-06-08 00:18) [51]> чем на свой страх и риск блокировать участки памяти.
Зачем? Все проще. Делим попалам, один поток — один половину, другой — другую.
← →
Pavia © (2007-06-10 02:53) [52]На самом деле надо понять как работают паролельные процессы. Тогда все станет ясно. При работе с паролельными процессами важна синхронизация. Но так как в данном контексте процессы работуют каждый со своими данными, то все должно работать и без нее. Остается только правельно синхронизовать момент старта и остановки процессов.
Как программист со средним знанием асм скажу следующее. Дельфи генерирует безобразный код. Так, что если я перепишу на асм то программа будет работать быстрее в большинстве случиев. А если уж и использовать mmx, то точно прирост будет значительный.
← →
Германн © (2007-06-10 03:01) [53]а
> Pavia © (10.06.07 02:53) [52]
Вань. Лучше не позорься! Такое количество грамматических ошибок - явный перебор!
← →
Strate © (2007-06-10 21:55) [54]А можно разбить битмап на 2 битмапа, на каждый зафигачить поток который уменьшит его и потом соединить :)
Но наврено это глупо, т.к. разбивка и склеивание долго буту работать
← →
Vovan Real (2007-06-10 23:57) [55]Удалено модератором
Примечание: в зеркало посмотри
← →
homm © (2007-06-11 00:07) [56]> [55] Vovan Real
Рад тебя снова видеть.
← →
DVM © (2007-06-11 00:10) [57]
> Pavia © (10.06.07 02:53) [52]
> Дельфи генерирует безобразный код
> Так, что если я перепишу на асм то программа будет работать
> быстрее в большинстве случиев
А если я твой пост перепишу на нормальном русском языке и без ошибок, то прочтя его, ты сам, может быть, поймешь, что ты не совсем прав насчет безобразного кода, который генерит Делфи.
Страницы: 1 2 вся ветка
Форум: "Основная";
Текущий архив: 2007.08.19;
Скачать: [xml.tar.bz2];
Память: 0.61 MB
Время: 0.045 c