Thực hiện song song

Một phần của tài liệu Song song hoá thuật toán Bames hut với OpenMP (Trang 50 - 57)

Theo đánh giá hiệu năng của treecode ở mục 3.2.2, ta thấy phần lớn thời gian chương trình dành cho việc thực hiện hàm walktree. Để tăng hiệu năng tính toán của treecode, ta tiến hành song song hóa treecode bằng cách song song hóa các hàm trên.

Khó khăn gặp phải trong khi tiến hành song song hóa treecode đó là sự phụ thuộc vào chương trình dịch. Với các trình biên dịch của các kiến trúc máy tính khác nhau sẽ

cho thời gian thực hiện từng hàm con trong chương trình treecode là khác nhau.

Ví dụ với trình biên dịch của máy IBM eServer Cluster 1600, hệ điều hành AIX5.2 với cấu hình như sau:

• 5 node tính toán pSeries 655, mỗi node gồm 8 CPU Power 4+ 64 bit RISC 1.7 GHz của IBM; cache 5.6MB ECC L2, 128MB ECC L3, băng thông: 72.3 GBps; 32GB RAM, băng thông bộ nhớ 51.2 GBps; 6x36 GB HDD. Năng lực tính toán tổng cộng khoảng 240 GFlops (mở rộng tối đa 768 GFlops/16 node).

• 1 node quản lý CSM p630: Power4+ 64 bit 1.2 GHz; cache 1.5 MB ECC L2, 8MB ECC L3, băng thông: 12.8 GBps; 1GB RAM, băng thông: 6.4 GBps; 6x36 GB HDD, DVD ROM.

• 1 node điều khiển phần cứng HCM: Intel Xeon 3.06 GHz, 1GB RAM, 40 GB HDD, DVD RAM.

Lê Thị Lan Phương 45

• Các node được kết nối với nhau thông qua HPS (High Performance Switch – Switch hiệu năng cao), băng thông 2GBps và GEthernet.

• Hệ thống lưu trữ chung: IBM DS4400 và EXP700 kết nối với cụm IBM 1600 thông qua cáp quang với băng thông 2Gbps.

• Các node chạy HĐH AIX 5L phiên bản 5.2 Kết quả profile của treecode trên IBM AIX sẽ là:

Với trình biên dịch của Intel (R) Xeon (TM) 4 CPU 2.40 GHz, thì phần trăm thời gian thực hiện các hàm của treecode là:

% cumulative self self total time seconds seconds calls ms/call ms/call name 42.3 13.85 13.85 .sqrt [8] 34.8 25.23 11.38 532480 0.02 0.02 .sumnode [9] 7.6 27.73 2.50 .__mcount [11] 5.4 29.50 1.77 161645903 0.00 0.00 .sqrtf [12] 4.0 30.81 1.31 16072949 0.00 0.00 .accept [13] 2.6 31.65 0.84 570149 0.00 0.03 .walktree_13_6 <cycle 1> [7] 0.8 31.91 0.26 .qincrement [15] 0.5 32.09 0.18 65 2.77 2.77 .diagnostics [18] 0.4 32.22 0.13 2480994 0.00 0.00 .subindex [19] 0.4 32.34 0.12 .__stack_pointer [20] 0.4 32.46 0.12 .qincrement1 [21] 0.3 32.55 0.09 266240 0.00 0.00 .loadbody [16] 0.2 32.61 0.06 65 0.92 1.25 .hackcofm [22] 0.1 32.64 0.03 65 0.46 0.46 .threadtree [25]

Lê Thị Lan Phương 46

Như vậy, với các trình biên dịch khác nhau, thời gian thực hiện các hàm của treecode là hoàn toàn khác. Vì vậy, việc đánh giá hàm nào tốn nhiều thời gian nhất cũng như cần phải tiến hành song song hóa như thế nào là vấn đề gặp nhiều khó khăn.

3.3.2.1 Phân tích hàm walktree

Hàm walktree là hàm đệ quy chính dùng trong khi tính lực. Nguyên mẫu của nó có dạng

void walktree(nodeptr *aptr, nodeptr *nptr, cellptr cptr, cellptr bptr,nodeptr p, real psize, vector pmid);

Hàm walktree tính lực hấp dẫn lên tất cả các hạt có trong node p thông qua việc duyệt đệ quy p và các con của nó. Tại mỗi thời điểm trong lượt duyệt đệ quy, thông tin của các node từ gốc tới p được lưu trữ trong một tập các node. Tập đó chính là tập các tương tác. Tập này được chia thành 2 tập cell và body riêng biệt, được trỏ bởi các con trỏ

tương ứng là cptr và bptr. Phần còn lại của cây được biểu diễn bởi một tập các active node, bao gồm node p và các node xung quanh nó trong không gian. Con trỏ trỏ tới các node này được lưu vào mảng nằm giữa aptr và nptr. Node p có kích thước là psize và vị

trí là pmid.

Trong vòng lặp chính, walktree duyệt qua tất cả các active node của p, kiểm tra xem node nào sẽđược thêm vào danh sách tương tác, và node nào gần với p đến mức phải kiểm tra các con của nó ở mức tiếp theo của quá trình duyệt đệ quy. Các cell được kiểm

Flat profile:

Each sample counts as 0.00195312 seconds.

% cumulative self self total time seconds seconds calls ms/call ms/call name 73.87 9.13 9.13 532480 0.02 0.02 sumnode 12.84 10.71 1.59 16013212 0.00 0.00 accept 10.21 11.97 1.26 569962 0.00 0.02 walktree 0.84 12.08 0.10 2466729 0.00 0.00 subindex 0.47 12.14 0.06 266240 0.00 0.00 loadbody 0.46 12.19 0.06 303722 0.00 0.00 walksub 0.27 12.23 0.03 65 0.51 0.51 diagnostics 0.25 12.26 0.03 520 0.06 0.07 hackcofm 0.22 12.28 0.03 520 0.05 0.05 threadtree 0.19 12.31 0.02 266240 0.00 0.03 gravsum 0.14 12.33 0.02 64 0.27 189.50 stepsystem

Lê Thị Lan Phương 47

tra thông qua hàm accept. Nếu cell cách khá xa p, nghĩa là tỉ số D/r là đủ nhỏ, cell được thêm vào danh sách tương tác của p. Ngược lại, kiểm tra tất cả các con của nó, và thêm vào danh sách các active node.

Nếu có danh sách active mới được tạo ra, thì tiếp tục duyệt cây đệ quy ở mức tiếp theo thông qua lời gọi hàm walksub. Hàm walksub thực hiện việc gọi hàm walktree tại các con của p. Ngược lại, nếu không có danh sách active mới nào, tiến hành kiểm tra p. Nếu p là body, thực hiện tính toán lực tại p bằng lời gọi hàm gravsum.

Nguyên mẫu của hàm walksub có dạng như sau:

void walksub(nodeptr *nptr, nodeptr *np, cellptr cptr, cellptr bptr,nodeptr p, real psize, vector pmid);

Các tham số trong hàm walksub có giá trị giống với các tham số trong hàm walktree tại lời gọi hàm. Có 2 trường hợp xảy ra: (adsbygoogle = window.adsbygoogle || []).push({});

• Nếu p là cell, khi đó walksub sẽ duyệt qua tất cả các con của p, và gọi hàm walktree tại mỗi nút con đó.

• Nếu p là body, walksub sẽ gọi hàm walktree đúng một lần duy nhất, để duyệt nốt danh sách active của nó.

Lê Thị Lan Phương 48

local void walktree(nodeptr *aptr, nodeptr *nptr, cellptr cptr, cellptr bptr, nodeptr p, real psize, vector pmid)

{

nodeptr *np, *ap, q; int actsafe;

if (Update(p)) { /* are new forces needed? */ np = nptr; /* start new active list */

actsafe = actlen - NSUB;/* leave room for NSUB more */

for (ap = aptr; ap < nptr; ap++)/* loop over active nodes */ if (Type(*ap) == CELL) { /* is this node a cell? */

if (accept(*ap, psize, pmid)) {/* does it pass the test?*/ Mass(cptr) = Mass(*ap); /* copy to interaction list */ SETV(Pos(cptr), Pos(*ap));

SETM(Quad(cptr), Quad(*ap));

cptr++; /* and bump cell array ptr */ } else { /* else it fails the test */

if (np - active >= actsafe) /* check list has room */ error("walktree: active list overflow\n");

for (q = More(*ap); q != Next(*ap); q = Next(q)) /* loop over all subcells */ *np++= q; /* put on new active list */ }

} else /* else this node is a body */ if (*ap != p) { /* if not self-interaction */ --bptr; /* bump body array ptr */ Mass(bptr) = Mass(*ap);/* and copy data to array */ SETV(Pos(bptr), Pos(*ap));

}

actmax = MAX(actmax, np - active); /* keep track of max active */ if (np != nptr) /* if new actives listed */ walksub(nptr, np, cptr, bptr, p, psize, pmid);

/* then visit next level */ else { /* else no actives left, so */ if (Type(p) != BODY) /* must have found a body */ error("walktree: recursion terminated with cell\n"); gravsum((bodyptr) p, cptr, bptr); /* sum force on the body */ }

} }

Lê Thị Lan Phương 49

3.3.2.2 Song song hóa treecode

Ý tưởng song song hóa treecode như sau:

• Sử dụng chỉ thị taskq được hỗ trợ bởi trình dịch của máy Intel, để song song hóa hàm đệ quy walktree.

• Với các hàm khác, sử dụng các chỉ thị Do/for để song song hóa vòng lặp.

Chỉ thị taskq thiết lập môi trường thực hiện các công việc (task). Khi gặp chỉ thị

taskq, một trong số các thread sẽ được chọn để thực hiện chỉ thị đó. Một hàng đợi rỗng

được tạo ra bởi thread đã chọn. Sau đó, đoạn chương trình nằm trong khối taskq sẽ được thực hiện bởi một thread đơn. Các thread còn lại chờ thực hiện khối công việc sẽ được thêm vào hàng đợi. Các chỉ thị task xác định một khối công việc có thể được thực hiện bởi nhiều thread khác nhau. Khi gặp chỉ thị task trong khai báo taskq, đoạn chương trình

local void walksub(nodeptr *nptr, nodeptr *np, cellptr cptr, cellptr bptr, nodeptr p, real psize, vector pmid)

{

real poff; nodeptr q; int k; (adsbygoogle = window.adsbygoogle || []).push({});

vector nmid;

poff = psize / 4; /* precompute mid. offset */ if (Type(p) == CELL) { /* fanout over descendents */ for (q = More(p); q != Next(p); q = Next(q)) {

/* loop over all subcells */ for (k = 0; k < NDIM; k++)

/* locate each's midpoint */

nmid[k] = pmid[k] + (Pos(q)[k] < pmid[k] ? - poff : poff); walktree(nptr, np, cptr, bptr, q, psize / 2, nmid);

/* recurse on subcell */ }

} else { /* extend virtual tree */ for (k = 0; k < NDIM; k++)

/* locate next midpoint */

nmid[k] = pmid[k] + (Pos(p)[k] < pmid[k] ? - poff : poff); walktree(nptr, np, cptr, bptr, p, psize / 2, nmid);

/* and search next level */ }

Lê Thị Lan Phương 50

nằm trong khai báo task về mặt lý thuyết sẽđược xếp vào hàng đợi. Hàng đợi sẽ kết thúc khi tất cả các công việc trên đó đã được hoàn thành.

Như vậy, với việc sử dụng hàng đợi, hàm walktree có thể được chỉnh sửa lại như

sau:

Trong hàm gravcal(), lời gọi hàm walktree sẽđược thêm các chỉ thị taskq và task của OpenMP.

Trong hàm walksub gọi đệ quy hàm walktree, do vậy sẽ thêm các chỉ thị của OpenMP vào hàm walksub như sau:

void gravcalc(void) {

………. ……….

active[0] = (nodeptr) root; /* initialize active list */ CLRV(rmid); /* set center of root cell */

/* Add parallel region */ #pragma omp parallel {

#pragma intel omp taskq

{

#pragma intel omp task {

walktree(active, active + 1, interact, interact + actlen, (nodeptr) root, rsize, rmid);

/* scan tree, update forces */ }

}

} /* end of parallel region */

cpuforce = cputime() - cpustart; /* store CPU time w/o alloc */ free(active);

free(interact); }

Lê Thị Lan Phương 51 (adsbygoogle = window.adsbygoogle || []).push({});

Khi biên dịch chương trình, các chỉ thị của OpenMP sẽđược thực hiện song song. Kết quả thực nghiệm được cho dưới đây.

Một phần của tài liệu Song song hoá thuật toán Bames hut với OpenMP (Trang 50 - 57)