Arsip: Transformasi ke multi thread

more 12 years ago
pebbie
guys, gw lagi ngoprek2 multithreading di delphi 7. kyknya (AFAIK) blum pernah ada yang bahas yang mau gw tanya. mohon bantuannya yah.
jadi gini, gw punya atribut bertipe array of integer di kelas tform1. sebut saja
...
public
arr : array of integer;
...
gw punya prosedur yang isinya mengubah tiap elemen di array (asumsi sudah diinisialisasi panjang dan nilai awalnya (misal 0)).
procedure TForm1.Button1Click(Sender: TObject);
var
i : integer;
begin
for i := 0 to high(arr) do
arr[i] := arr[i] + 1;
end;
gw mo bikin kelas turunan tthread (sebut saja TMyThread) yang isi method execute-nya (arr[i] := arr[i] + 1) dari prosedur di atas. sejumlah (n) objek TMythread dipegang di Form1.
nah, pertanyaannya..
gimana caranya mendelegasikan n thread ini supaya menggantikan fungsi button1click?
NB:n mungkin tidak sama dengan panjang array arr, kalau bisa sejumlah thread ini hanya perlu di-create sekali (sebelum 'for') dan tetap hidup sampai tugas selesai
NB(lagi):bwt yang bingung gw mau ngapain, gw lagi pengen bikin imitasi dari paralelisasi for (#pragma omp parallel for) di OpenMP (atau Parallel Extension di .NET 2008) ke Delphi 7
thx b4
more 12 years ago
asiyrob
coba bantu..walaupun ga' begitu ngerti??
dari pengamatan sekilas, maka ane mendapat hipotesis bahwa=
1. program akan error/debug ketika button1 diklik terus menerus (silahkan coba)!!
2. gunakan function (silahakan berexplorasi)!!
3. program harus dibuat realtime, bisa gunakan timer/msg dari window
maaf klo hipotesis ane salah.. :mrgreen: :mrgreen:

more 12 years ago
pebbie
Gw berhasil bikin tapi ada masalah..
ini file Unit2.pas isinya turunan kelas TThread
unit Unit2;
interface
uses
Classes, Windows, SysUtils;
type
TThreadState = (tsRunning, tsIdle, tsDone);
TArrElmtModifier = class(TThread)
private
{ Private declarations }
FX, FY, FID: integer;
FState : TThreadState;
protected
procedure Execute; override;
procedure NotifyStart;
procedure NotifyDone;
public
constructor Create(AID:integer);
procedure Run;
procedure Done;
property X : integer read FX write FX;
property Y : integer read FY write FY;
property ID : integer read FID write FID;
property State : TThreadState read FState write FState;
end;
implementation
uses Unit1;
{ TArrElmtModifier }
constructor TArrElmtModifier.Create(AID:integer);
begin
inherited Create(false);
FID := AID;
X := 0;
Y := 0;
State := tsIdle;
self.FreeOnTerminate := false;
end;
procedure TArrElmtModifier.Done;
begin
FState := tsDone;
end;
procedure TArrElmtModifier.Execute;
begin
{ Place thread code here }
while (FState<>tsDone) do begin
if (FState=tsRunning) then begin
{ Do Thread Task here }
Form1.arr[Y][X] := Form1.arr[Y][X] + 10;
NotifyDone;
{ Notify when task done }
end;
sleep(1);
end;
end;
procedure TArrElmtModifier.NotifyDone;
begin
Form1.AcceptDone(FID);
State := tsIdle;
end;
procedure TArrElmtModifier.NotifyStart;
begin
Form1.Memo1.Lines.Add('Thread#'+inttostr(FID)+'started');
end;
procedure TArrElmtModifier.Run;
begin
State := tsRunning;
end;
end.
dan ini file Unit1.pas yang menyimpan array (arr). prosedur Button1Click merupakan acuan (dijalankan secara sekuensial tanpa threading) sedangkan Button2Click adalah versi multithreading. pekerjaan utamanya adalah menambahkan tiap elemen array arr dengan 10.
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, Unit2, StdCtrls, Spin;
type
TForm1 = class(TForm)
Memo1: TMemo;
SpinEdit1: TSpinEdit;
Button2: TButton;
Label1: TLabel;
Label2: TLabel;
SpinEdit2: TSpinEdit;
Button1: TButton;
procedure Button2Click(Sender: TObject);
procedure Button1Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
nthreads : integer;
threadflags : array of boolean;
threads : array of TArrElmtModifier;
arr : array of array of integer;
tq : integer;
procedure Prepare;
procedure DispatchThreads;
procedure AcceptDone(idx:integer);
end;
var
Form1: TForm1;
implementation
{$R *.dfm}
procedure TForm1.AcceptDone(idx: integer);
begin
threadflags[idx] := false;
//memo1.lines.Add('done#'+inttostr(idx));
end;
procedure TForm1.DispatchThreads;
var
i, j, k : integer;
busy : boolean;
tmp : tstrings;
start, finish : longint;
begin
Memo1.Lines.Clear;
start := GetTickCount;
{ ordered scheduling }
for j := 0 to high(arr) do
for i := 0 to high(arr[j]) do begin
{ schedule iteration(i,j) }
busy := true;
repeat
k := tq; //GetNextAvailableThread
//if not threadflags[k] then begin
if threads[k].State = tsIdle then begin
threadflags[k] := true;
//memo1.lines.add(format('dispatch (%d,%d) to thread#%d',[i,j,k]));
threads[k].X := i;
threads[k].Y := j;
threads[k].Run;
busy := false;
break;
end;
tq := (tq + 1) mod length(threads);
Application.ProcessMessages;
until not busy;
end;
{ barrier, wait until all task finished }
repeat
busy := false;
for k := 0 to high(threads) do begin
if threadflags[k] then begin
busy := true;
break;
end;
end;
Application.ProcessMessages;
until not busy;
finish := GetTickCount;
{ clean up threads }
for i := 0 to high(threads) do
threads[i].State := tsDone;
{ display changes }
tmp := TStringlist.Create;
for j := 0 to high(arr) do begin
tmp.Clear;
for i := 0 to high(arr[j]) do begin
tmp.add(inttostr(arr[j][i]));
end;
memo1.Lines.add(tmp.CommaText);
end;
Memo1.Lines.Add('Done in '+inttostr(finish-start)+' ms');
tmp.Free;
end;
procedure TForm1.Button2Click(Sender: TObject);
var
i : integer;
begin
Prepare;
nthreads := SpinEdit1.Value;
setlength(threadflags, nthreads);
setlength(threads, nthreads);
for i := 0 to high(threads) do begin
threadflags[i] := false;
threads[i] := TArrElmtModifier.Create(i);
end;
DispatchThreads;
end;
procedure TForm1.Button1Click(Sender: TObject);
var
i, j, k : integer;
start, finish : cardinal;
tmp : TStrings;
begin
Prepare;
Memo1.Lines.Clear;
start := GetTickCount;
{ ordered scheduling }
for j := 0 to high(arr) do
for i := 0 to high(arr[j]) do begin
arr[j][i] := arr[j][i] + 10;
end;
finish := GetTickCount;
{ display changes }
tmp := TStringlist.Create;
for j := 0 to high(arr) do begin
tmp.Clear;
for i := 0 to high(arr[j]) do begin
tmp.add(inttostr(arr[j][i]));
end;
memo1.Lines.add(tmp.CommaText);
end;
Memo1.Lines.Add('Done in '+inttostr(finish-start)+' ms');
tmp.Free;
end;
procedure TForm1.Prepare;
var
i,n : integer;
begin
n := SpinEdit2.Value;
if length(arr)>0 then
for i := 0 to high(arr) do
setlength(arr[i], 0);
setlength(arr, n);
for i := 0 to high(arr) do
setlength(arr[i], n);
tq := 0;
end;
end.
kesimpulannya, kode yang multithread itu berjalan lebih lambat daripada yang sekuensial.
memang sih operasi yang diparalelin itu terlalu sederhana sehingga overhead untuk komunikasi dan delegasi thread terlalu besar.
- kalo diasumsikan task untuk tiap thread cukup kompleks secara komputasi, apa mungkin mekanisme delegasi multithread ini bisa dioptimasi lagi?
- apa cara yang gw pake terlalu mahal di kelas turunan TThread?
more 12 years ago
DelphiExpert
1. Manage thread dalam sebuah List; kemudian utk controlling anda dapat melakukan perulangan sebanyak thread-count. thread[0].resume, suspend etc.
2. dalam execute, jika pekerjaan selesai, thread harus men-suspend dirinya sendiri utk kemudian dibangunkan dari thread lain (resume) apabila ada data / pekerjaan baru

more 12 years ago
DelphiExpert
wah, komen saya diatas harusnya uda terpost beberapa menit yg lalu... perasaan udah tonjok tombol submit, kok belum terkirim... :mrgreen:

more 12 years ago
DelphiExpert
Parallel programming seharusnya menghasilkan kinerja lebih cepat daripada dikerjakan sekuensial. artinya apa? artinya ada yg salah dalam implementasinya. banyak hal misal: salah design, optimasi kode, synchronisasi yg kurang tepat (to many locking) dll.
Hal ini sangat berpengaruh pada hasil akhir :)

more 12 years ago
pebbie
bro DE, yang ke 1 udah diimplementasi pake array (threads di Form1), yang ke 2 udah pake property State di kelas TArrElmtModifier (tipe TThreadState {tsIdle untuk suspend, tsDone untuk otomatis terminate})
di kode di atas nggak ada locking, bahkan notifydone pun nggak di synchronize biar cepet.
programnya sih udah cukup menggambarkan peningkatan (dengan acuan 1 thread).. maka penambahan n thread akan mempercepat eksekusi sebesar tn/t1 tapi tetap saja kalo kode yang sekuensial itu pas diukur waktunya 0 ms.
:(
apa memang contoh kasusnya nggak relevan untuk parallel programming yah? karena secara sekuensial pun udah cukup cepat..
artinya ada yg salah dalam implementasinya. banyak hal misal: salah design, optimasi kode, synchronisasi yg kurang tepat (to many locking) dll.kalo menurut bro DE, yang salah dari kode di atas di mana ya kira-kira?

more 12 years ago
mat_koder
Sumbang saran dari saya:
Sekalipun dalam setiap thread , main tasknya "computation intensive: , saya nyaranin bikin tambahan satu atau dua thread saja ( disesuaikan dngan jumlah core CPU yg ada dlm mesin tsb). Main thread me-manage GUI dan ngontrol thread tsb.
Windows kan pake konsep preemptive multitasking ( setiap thread ngga harus diberi slice waktu yg sama) , jadi ngga selalu berarti makin banyak thread makin banyak jatah persentase CPU cycle.
Emang jika bersamaan dan bersaing dengan aplikasi laen yg juga computation intensive, konsep makin banyak thread makin baik mungkin akan berhasil, namun untuk pemakaian umum rasanya engga-lah.
Yang jadi pertanyaan tentunya adalah apakah Delphi compiler sudah cukup smart untuk memisahkan ( mendistribusikan) masing-masing thread yg di-create oleh aplikasi supaya dikerjakan oleh CPU core yg berbeda pada mesin multi core.
Ada yg tahu mengenai hal ini?

more 12 years ago
pebbie
ternyata ketika dijalankan di luar IDE, berjalan jauh lebih cepat sehingga bisa sebanding dengan eksekusi sekuensial. laporannya sudah saya tulis di blog saya. kesimpulannya, eksperimen saya di atas bisa dibilang cukup berhasil.
setahu saya preemptive multi-tasking hanya berlaku pada proses, bukan thread. dan hipotesis saya bahwa tiap thread dalam suatu proses dialokasikan time-slice yang sama dan proses yang memiliki beberapa thread memiliki prioritas untuk preempted yang lebih kecil. Buktinya adalah program yang memanfaatkan thread di mesin yang memiliki lebih dari 1 core dalam 1 prosesor (multicore) ketika dilihat dengan task manager maka CPU Usage-nya bisa mencapai 100% sedangkan jika diimplementasi tanpa threading maka maksimum CPU Usage-nya adalah 50 % (untuk dual core CPU).
urusan distribusi thread ini saya juga masih belum paham apakah ini tanggung jawab compiler atau justru runtime environment yang dalam hal ini adalah operating system. ada yang punya informasi yang lebih akurat?

more 12 years ago
pebbie
oya, lupa bilang terima kasih sama bung mat koder.
secara otomatis/default pengelolaan GUI sudah memiliki satu thread sendiri sehingga thread lainnya merupakan tambahan dari thread ini (TApplication sepertinya). di eksperimen saya, dengan menggunakan 2 thread, ketika dilihat menggunakan task manager, thread untuk proses ybs tercantum sebagai 3 thread.
more ...
- Pages:
- 1
- 2
reply |
Report Obsolete
Last Articles
- Project Group dalam Lazarus
- FastPlaz Database Explorer
- Release: FastPlaz Super Mom v0.12.22
- PascalClass #3: Web Development with Free Pascal
- Makna Pascal di Pascal Indonesia
- Kulgram : Instalasi Lazarus di Perangkat Berbasis ARM
- PascalClass #1: Analisa Database dan Machine Learning
- PascalTalk #6: (Podcast) Kuliah IT di luar negeri, susah gak sih?
- Mengenal OXYGENE – Pascal For .NET
- PascalTalk #5: UX: Research, Design and Engineer
Last Topic
- PascalTalk #6: (Podcast) Kuliah IT di luar negeri, susah gak sih?
by LuriDarmawan in Tutorial & Community Project more 3 months ago - PascalTalk #5: UX: Research, Design and Engineer
by LuriDarmawan in Tutorial & Community Project more 4 months ago - PascalTalk #4: Obrolan Ringan Seputar IT
by LuriDarmawan in Tutorial & Community Project more 4 months ago - PascalTalk #2: Membuat Sendiri SMART HOME
by LuriDarmawan in Tutorial & Community Project more 4 months ago - PascalTalk #3: RADically Fast and Easy Mobile Apps Development with Delphi
by LuriDarmawan in Tutorial & Community Project more 4 months ago - PascalTalk #1: Pemanfaatan Artificial Intelligence di Masa Covid-19
by LuriDarmawan in Tutorial & Community Project more 4 months ago - Tempat Latihan Posting
by LuriDarmawan in OOT more 1 years ago - Archive
- Looping lagi...
by idhiel in Hal umum tentang Pascal Indonesia more 8 years ago - [ask] koneksi ke ODBC user Dsn saat runtime dengan ado
by halimanh in FireBird more 8 years ago - Validasi menggunakan data tanggal
by mas_kofa in Hal umum tentang Pascal Indonesia more 8 years ago
Random Topic
- Posisi Alligment Center di TEDIT
by DeulleDo-X in Hal umum tentang Pascal Indonesia more 13 years ago - program OCR pake delphi
by luina in Hal umum tentang Pascal Indonesia more 12 years ago - Tanya Apakah...
by johnizzy in Hal umum tentang Pascal Indonesia more 12 years ago - extract icon
by bboyz in Tip n Trik Pemrograman more 13 years ago - the best report
by wiedhodho in Multimedia & Graphic Enhancement more 14 years ago - bagaimana me-reset canvas pada Image?
by yohan_siswanto in Form Enhancement & Graphical Controls more 14 years ago - Image Processing & Robotik dan Delphi???
by barcodebima in Enginering more 13 years ago - MySQL = Sun
by LuriDarmawan in MySQL more 13 years ago - validasi tanggal di TmaskEdit __/__ /___
by maulaku in Tip n Trik Pemrograman more 13 years ago - [HELPP ]Tanya cara set Regional Option dari script dong
by MingMing in Tip n Trik Pemrograman more 14 years ago