Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2007.08.19;
Скачать: CL | DM;

Вниз

Обработка 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 как-то увеличить скорость грамотного(!) кода достаточно трудно.



Страницы: 1 2 вся ветка

Текущий архив: 2007.08.19;
Скачать: CL | DM;

Наверх




Память: 0.58 MB
Время: 0.025 c
15-1185249634
de.
2007-07-24 08:00
2007.08.19
Как удалить себя из списка?


3-1178105054
Boxer2007
2007-05-02 15:24
2007.08.19
Вычисления в cxDrid


1-1180368669
Dmitry_177
2007-05-28 20:11
2007.08.19
Перехват клавиатуры


15-1184940907
VirEx
2007-07-20 18:15
2007.08.19
посоветуйте кондиционер


15-1184588170
Ricks
2007-07-16 16:16
2007.08.19
Творческие идеи