Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Основная";
Текущий архив: 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
15-1184842707
EGFEFG
2007-07-19 14:58
2007.08.19
Компьютер сам презагружается


11-1168181437
retr
2007-01-07 17:50
2007.08.19
Есть ли TCP клиент для KOL умеющий работать через SOCKS 4/5?


15-1185006460
Bratyk
2007-07-21 12:27
2007.08.19
Как сохранить проект в exe - файл


15-1184297566
макк
2007-07-13 07:32
2007.08.19
Как узнать откуда территориально такой-то ай-пи адрес?


4-1171957830
Sunflower
2007-02-20 10:50
2007.08.19
Как удаленно установить клиентскую часть программы?





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский