5. Bố cục đề tài
3.2. Kết quả chạy thử nghiệm
Các thuật toán dưới đây được thực nghiệm trên một máy tính Intel Core i5 2.5 GHz, RAM 3 GB, chạy windows 7 32-bit, card đồ họa GeForce 610M.
Ngôn ngữ sử dụng: Thuật toán được triển khai bằng ngôn ngữ C, và sử dụng hàm trong thư viện CUDA.
Dijkstra
Dưới đây là bảng kết quả chạy thử nghiệm và đồ thị biểu diễn thời gian chạy của thuật toán Dijkstra tuần tự và Dijkstra chạy song song bằng CUDA.
Bảng 3.1: Kết quả thực hiện Dijkstra
Số đỉnh
Thời gian chạy / giây
Dijkstra tuần tự Dijkstra CUDA
1000 0.042 0.196 2000 0.172 0.465 3000 0.406 0.766 4000 0.705 1.111 5000 1.110 1.550 6000 1.610 1.950 7000 2.150 2.330 8000 2.850 2.900 9000 3.630 3.450 10000 4.550 3.950 11000 5.410 4.450 12000 6.391 4.766 13000 7.512 5.430 14000 9.036 6.092 15000 10.059 7.128
Hình 3.1: Đồ thị biểu diễn thời gian chạy Dijkstra
Hình 3.2: Kết quả chạy thử nghiệm 15 nghìn đỉnh dùng Dijkstra tuần tự 0 2 4 6 8 10 12 1000 2000 3000 4000 5000 6000 7000 8000 9000 10000 11000 12000 13000 14000 15000
Hình 3.3: Kết quả chạy thử nghiệm 15 nghìn đỉnh dùng Dijkstra CUDA
Hai hình 3.2 và hình 3.3 là kết quả chạy thử nghiệm với 15 nghìn đỉnh tương ứng là Dijkstra tuần tự và Dijkstra CUDA, với đỉnh xuất phát là 7 đi đến tất cả các đỉnh còn lại (ở đây chỉ xuất ra 10 đường đi). Kết quả cho thấy cả hai Dijkstra tuần tự và Dijkstra CUDA cho ra các chi phí và các con đường là giống nhau.
Nhận xét:
Thuật toán Dijkstra tuần tự thực hiện nhanh hơn so với chạy song song với CUDA khi dữ liệu đầu vào nhỏ, cụ thể từ 7 nghìn đỉnh trở xuống thì việc thực hiện tuần tự sẽ chạy nhanh hơn.
Nhưng khi dữ liệu đầu vào lớn hơn 7 nghìn đỉnh thì thuật toán Dijkstra tuần tự có thời gian hoàn thành chậm hơn so với chạy song song bằng CUDA.
Lý do là vì với số đỉnh ít thì việc tính toán vẫn nằm trong khả năng tính toán của CPU do chương trình Dijkstra tuần tự không phải trải qua giai đoạn đưa dữ liệu từ RAM (memory Host) sang VRAM (memory Device) như chương trình CUDA song song. Nhưng với số đỉnh tăng dần thì chương trình tuần tự trải qua nhiều lần lặp do đó sẽ chạy chậm hơn chương trình song song.
Ford Bellman
Dưới đây là bảng kết quả chạy thử nghiệm và đồ thị biểu diễn thời gian chạy của thuật toán Ford Bellman tuần tự và Ford Bellman chạy song song với phần tối ưu nhãn 1D (1 chiều) và Ford Bellman chạy song song với phần tối ưu nhãn 2D (2 chiều).
Bảng 3.2: Kết quả thực hiện Ford Bellman
Số đỉnh
Thời gian chạy / giây Ford Bellman tuần
tự Ford Bellman CUDA -1D Ford Bellman CUDA -2D 1000 0.095 0.380 0.013 2000 0.462 0.560 0.039 3000 0.939 0.920 0.086 4000 1.511 1.145 0.145 5000 3.644 2.249 0.300 6000 4.147 2.398 0.378 7000 6.774 2.916 0.528 8000 7.950 3.179 0.690 9000 10.805 3.808 0.909 10000 13.500 4.956 1.172 11000 17.680 5.599 1.406
Hình 3.4: Đồ thị biểu diễn thời gian chạy Ford Bellman
Hình 3.5: Kết quả chạy thử nghiệm 11 nghìn đỉnh dùng Ford Bellman tuần tự 0 2 4 6 8 10 12 14 16 18 20 1000 2000 3000 4000 5000 6000 7000 8000 9000 10000 11000
Ford Bellman Tuần Tự Ford Bellman CUDA-1D
Hình 3.6: Kết quả chạy thử nghiệm 11 nghìn đỉnh dùng Ford Bellman CUDA 1D
Ba hình 3.5 và hình 3.6 và hình 3.7 là kết quả chạy thử nghiệm với 11 nghìn đỉnh tương ứng là Ford Belman tuần tự và Ford Bellman CUDA 1D và Ford Bellman CUDA 2D, với đỉnh xuất phát là 9 đi đến tất cả các đỉnh còn lại (ở đây chỉ xuất ra 10 đường đi). Kết quả cho thấy cả ba Ford Bellman tuần tự và Ford Bellman CUDA 1D và Ford Bellman CUDA 2D cho ra các chi phí và các con đường là giống nhau.
Nhận xét:
Thuật toán Ford Bellman tuần tự thực hiện chậm hơn so với chạy song song với CUDA 2D ở mọi dữ liệu đầu vào (số đỉnh). Lý do vì Ford Bellman tuần tự phải dùng hai vòng lặp for cho phần khởi tạo mảng a (trong khi đó CUDA 2D không có vòng lặp for nào) và một vòng lặp for cho phần khởi tạo lưu vết pre (trong khi đó CUDA 2D không có vòng lặp for nào) và ba vòng lặp for lồng nhau cho phần lặp (phần tối ưu) trong khi đó CUDA 2D chỉ có 1 vòng lặp for.
Thuật toán Ford Bellman tuần tự thực hiện nhanh hơn so với chạy song song với CUDA 1D khi dữ liệu đầu vào nhỏ, cụ thể là từ 3 nghìn đỉnh trở xuống. Khi dữ liệu lớn hơn 3 nghìn đỉnh thì Ford Bellman tuần tự tỏ ra chậm hơn so với CUDA 1D. Lý do càng nhiều đỉnh thì vòng for lặp càng nhiều.
Lý do là vì với số đỉnh ít thì việc tính toán vẫn nằm trong khả năng tính toán của CPU do chương trình Ford Bellman tuần tự không phải trải qua giai đoạn đưa dữ liệu từ RAM (memory Host) sang VRAM (memory Device) như chương trình CUDA song song. Nhưng với số đỉnh tăng dần thì chương trình tuần tự trải qua nhiều lần lặp do đó sẽ chạy chậm hơn chương trình song song.
Floyd
Dưới đây là bảng kết quả chạy thử nghiệm và đồ thị biểu diễn thời gian chạy của thuật toán Floyd tuần tự và Floyd chạy song song với phần tối ưu nhãn 1D (1 chiều) và Floyd chạy song song với phần tối ưu nhãn 2D (2 chiều).
Bảng 3.3: Kết quả thực hiện Floyd
Số đỉnh
Thời gian chạy / giây
Floyd tuần tự Floyd CUDA -1D Floyd CUDA -2D
1000 21.726 31.255 1.027 1500 70.117 66.822 3.370 2000 166.150 114.964 7.843 2500 319.720 178.364 15.514 3000 557.781 266.770 26.503 3500 885.711 363.593 42.329 4000 * 451.551 61.244 4500 * 575.343 89.679 5000 * 714.423 121.139 6000 * * 205.820 7000 * * 330.257
Hình 3.8: Đồ thị biểu diễn thời gian chạy Floyd
Hình 3.9: Kết quả chạy thử nghiệm 3 nghìn 5 trăm đỉnh dùng Floyd tuần tự
0 100 200 300 400 500 600 700 800 900 1000 1000 1500 2000 2500 3000 3500 4000 4500 5000 6000 7000
Hình 3.10: Kết quả chạy thử nghiệm 3 nghìn 5 trăm đỉnh dùng Floyd CUDA 1D
Ba hình 3.9 và hình 3.10 và hình 3.11 là kết quả chạy thử nghiệm với 3 nghìn 5 trăm đỉnh tương ứng là Floyd tuần tự và Floyd CUDA 1D và Floyd CUDA 2D, với đỉnh đích là 3499 (ở đây chỉ xuất ra 9 đường đi). Kết quả cho thấy cả ba Floyd tuần tự và Floyd CUDA 1D và Floyd CUDA 2D cho ra các chi phí và các con đường là giống nhau.
Nhận xét:
Thuật toán Floyd tuần tự thực hiện chậm hơn so với chạy song song với CUDA 2D ở mọi dữ liệu đầu vào (số đỉnh). Lý do vì Floyd tuần tự phải dùng hai vòng lặp for cho phần khởi tạo mảng a (trong khi đó CUDA 2D không có vòng lặp for nào) và cho phần khởi tạo lưu vết pre (trong khi đó CUDA 2D không có vòng lặp for nào) và ba vòng lặp for lồng nhau cho phần lặp (phần tối ưu) trong khi đó Floyd CUDA 2D chỉ có 1 vòng lặp for.
Thuật toán Floyd tuần tự thực hiện nhanh hơn so với chạy song song với Floyd CUDA 1D khi dữ liệu đầu vào (số đỉnh) nhỏ hơn 1500 đỉnh, với dữ liệu lớn hơn 1500 đỉnh thì thuật toán tuần tự thực hiện chậm hơn so với Floyd CUDA 1D.
Nhận xét chung
Với số đỉnh ít thì việc tính toán vẫn nằm trong khả năng tính toán của CPU do chương trình tuần tự không phải trải qua giai đoạn đưa dữ liệu từ RAM (memory Host) sang VRAM (memory Device) như chương trình song song. Nhưng với số đỉnh tăng dần thì chương trình tuần tự trải qua nhiều lần lặp do đó sẽ chạy chậm hơn chương trình song song.
KẾT LUẬN
Đề tài với mục tiêu chính là song song hóa được một số thuật toán tìm đường đi ngắn nhất tuần bằng CUDA, để làm giảm thời gian hoàn thành của một số thuật toán.
Các thuật toán tìm đường đi tuần tự đã được phân tách ra thành những phần có thể song song hóa và thực hiện song song hóa bằng CUDA. Việc phân chia dữ liệu cho mỗi luồng (threads) thực hiện một công việc nhất định đã làm cho bài toán song song CUDA trở nên nhanh hơn so với bài toán chạy tuần tự.
Tuy nhiên do giới hạn về kiến thức và thời gian, chương trình vẫn chưa đáp ứng được khi dữ liệu đầu vào quá lớn (số lượng đỉnh lớn cỡ vài trăm nghìn hoặc vài triệu đỉnh) thì chương trình không thể thực hiện được (do không đủ bộ nhớ lưu trữ và không đủ số thread để thực hiện song song, số thread là có giới hạn tùy theo mỗi loại card đồ họa).
Trong thời gian tới, đề tài cần được mở rộng thêm việc cho phép chương trình thực hiện chạy với dữ liệu lớn cỡ vài triệu đỉnh. Bên cạnh đó, chương trình cũng có thể được viết bằng CUDA.net.
TÀI LIỆU THAM KHẢO Tài liệu tiếng việt
[1] Trương Văn Hiệu (2011), “Nghiên cứu các giải thuật song song trên hệ thống xử lý đồ
họa GPU đa lõi”, luận văn thạc sĩ, trường Đại học Đà Nẵng.
[2] Lê Minh Hoàng (2002), “Giải thuật & Lập trình”, Bài giảng chuyên đề, Đại học Sư phạm Hà Nội.
[3] Nguyễn Thị Thùy Linh (2009), “Tính toán hiệu năng cao với bộ xử lý đồ họa GPU và
ứng dụng”, luận văn thạc sĩ, trường Đại học Công nghệ Hà Nội.
Tài liệu tiếng anh
[4] Jason Sanders, Edward Kandrot, “CUDA by example”, an introduction to General- Purpose GPU programming.
[5] Maciej Matyka, “GPGPU programming on example of CUDA”, Institute of Theoretical Physics University of Wroclaw.
[6] NVIDIA, “High performance computing with CUDA”, Users Group Conference San Diego, CA June 15, 2009.
[7] Pawan Harish, P. J. Narayanan, “Accelerating large graph algorithms on the GPU
using CUDA”, Center for Visual Information Technology International Institute of
Information Technology Hyderabad, INDIA.
Tài liệu internet
[8] Kỹ thuật lập trình song song, truy cập tháng 8 năm 2012 http://diendan.congdongcviet.com/showthread.php?t=19731 [9] Thuật toán Floyd, truy cập tháng 10 năm 2012