Arsip: Transformasi ke multi thread

more 16 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 16 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 16 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 16 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 16 years ago
DelphiExpert
wah, komen saya diatas harusnya uda terpost beberapa menit yg lalu... perasaan udah tonjok tombol submit, kok belum terkirim... :mrgreen:

more 16 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 16 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 16 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 16 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 16 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
AI Forward

🚀 We're thrilled to partner with Alibaba Cloud for "AI Forward - Alibaba Cloud Global Developer Summit 2025" in Jakarta! Join us and explore the future of AI. Register now:
https://int.alibabacloud.com/m/1000400772/
#AlibabaCloud #DeveloperSummit #Jakarta #AIFORWARD
Last Articles
Last Topic
- PascalTalk #6: (Podcast) Kuliah IT di luar negeri, susah gak sih?
by LuriDarmawan in Tutorial & Community Project more 4 years ago - PascalTalk #5: UX: Research, Design and Engineer
by LuriDarmawan in Tutorial & Community Project more 4 years ago - PascalTalk #4: Obrolan Ringan Seputar IT
by LuriDarmawan in Tutorial & Community Project more 4 years ago - PascalTalk #2: Membuat Sendiri SMART HOME
by LuriDarmawan in Tutorial & Community Project more 4 years ago - PascalTalk #3: RADically Fast and Easy Mobile Apps Development with Delphi
by LuriDarmawan in Tutorial & Community Project more 4 years ago - PascalTalk #1: Pemanfaatan Artificial Intelligence di Masa Covid-19
by LuriDarmawan in Tutorial & Community Project more 4 years ago - Tempat Latihan Posting
by LuriDarmawan in OOT more 5 years ago - Archive
- Looping lagi...
by idhiel in Hal umum tentang Pascal Indonesia more 12 years ago - [ask] koneksi ke ODBC user Dsn saat runtime dengan ado
by halimanh in FireBird more 12 years ago - Validasi menggunakan data tanggal
by mas_kofa in Hal umum tentang Pascal Indonesia more 12 years ago
Random Topic
- Membatasi Gerakan Kursor Mouse?
by ianhade in Tip n Trik Pemrograman more 17 years ago - Tutorial Delphi ke MySQL dengan ADO
by amalia79 in MySQL more 17 years ago - membaca data dari weighing indicator XK3190 A9
by lagisedih in Network, Files, I/O & System more 16 years ago - menghitung string 5 digit
by donlego in Tip n Trik Pemrograman more 17 years ago - Menyeleksi Transaksi untuk laporan
by adixp in Tutorial & Community Project more 17 years ago - Turbo Deplhi ????
by opera in OOT more 18 years ago - Bikin BackGround Gambar
by Irvin in Hal umum tentang Pascal Indonesia more 17 years ago - CR10: Error 536 incorrect log on parameters
by peddy in Reporting more 17 years ago - Solusi Dong !
by umarbakri in Hal umum tentang Pascal Indonesia more 17 years ago - Project Tertentu pd Delphi 6 & 7 Tidak bisa breakpoint
by fafenail in Hal umum tentang Pascal Indonesia more 19 years ago