Tiểu luận môn tính toán lưới LẬP TRÌNH SONG SONG TRÊN C SHARP VÀ .NET

23 610 0
Tiểu luận môn tính toán lưới LẬP TRÌNH SONG SONG TRÊN C SHARP VÀ .NET

Đang tải... (xem toàn văn)

Tài liệu hạn chế xem trước, để xem đầy đủ mời bạn chọn Tải xuống

Thông tin tài liệu

ĐẠI HỌC QUỐC GIA TP. HỒ CHÍ MINH TRƯỜNG ĐẠI HỌC CÔNG NGHỆ THÔNG TIN  BÀI THU HOẠCH TÍNH TOÁN LƯỚI LẬP TRÌNH SONG SONG TRÊN C SHARP VÀ .NET GVHD: TS. NGUYỄN PHI KHỨ HVTH: TRẦN NGUYÊN PHONG CH1101028 TP. Hồ Chí Minh, tháng 7 năm 2013 MỤC LỤC 1. Mở đầu 2 2. Các kỹ thuật lập trình song song 3 2.1 Lập trình tác vụ 3 2.1.1 Cơ bản về tác vụ 3 2.1.2 Thực hiện dừng tác vụ 4 2.1.3 Thực hiện chờ tác vụ 6 2.1.4 Bắt ngoại lệ khi chạy tác vụ 8 2.1.5 Các lỗi thường và cách xử lý 9 2.2 Chia sẻ dữ liệu 10 2.2.1 Đồng bộ hóa tác vụ 10 2.2.2 Các kỹ thuật đồng bộ hóa tác vụ 11 2.2.3 Cấu trúc dữ liệu dùng để chia sẻ dữ liệu 16 2.3 Điều hướng tác vụ 18 2.3.1 Sử dụng kỹ thuật Task Continuations 18 2.3.2 Tạo tác vụ con 19 2.4 Vòng lặp song song 21 3. Kết luận 22 TÀI LIỆU THAM KHẢO 23 Tính toán lưới Trang 2 1. Mở đầu Lĩnh vực công nghệ thông tin đã được ứng dụng rộng rãi trong tất cả các lĩnh vực của cuộc sống. Hiện nay, công nghệ thông tin đã được xem như là các nền tảng cốt lõi trong một số lĩnh vực, đặc biệt các lĩnh vực liên quan đến tính toán và mô phỏng. Với các yêu cầu xử lý tính toán hiệu năng cao tăng nhanh về số lượng của như chất lượng ví dụ như dự báo thời tiết, mô phỏng sinh học… các máy tính phải được nâng cấp liên tục về phần cứng để có được tính toán hiệu năng cao. Xu hướng mở rộng các bán dẫn (transitors) trên các CPU truyền thống đã đạt nhiều thành công trong quá khứ nhưng đối với hiện tại thì việc mở rộng đã tiến tới gần những giới hạn nhất định. Trong khi yêu cầu mở rộng về năng lực tính toán là không giới hạn nhưng việc gia tăng transitor trên đơn nhân CPU lại gặp giới hạn về kỹ thuật thì xu hướng đa nhân hóa các CPU trên máy tính đang là xu hướng chính trong việc mở rộng năng lực tính toán cho các máy tính. Hiện nay, đối với các máy tính phổ thông đã tiếp cận cơ bản với CPU có 8 nhân riêng biệt để giải quyết nhanh chóng nhiều vấn đề riêng biệt khác nhau. Tuy nhiên, đối với đa số các lập trình viên phổ thông thao tác lập trình cho các phần mềm hoạt động tối ưu trên các CPU đa nhân vẫn còn đang là vấn đề khó khăn. Khó khăn vì lập trình song song hay mở rộng ra là tính toán song song là những phương pháp thao tác khó, khó sửa lỗi chương trình, khó phát triển phần mềm theo một số quy trình phần mềm hiện nay… Nhưng với những yêu cầu về tính toán hiện nay thì xu hướng lập trình song song là xu hướng tất yếu đối với các lập trình viên. Trong phạm vi tiểu luận này, tác giả trình bày một số kỹ thuật cơ bản nhất trong lập trình song song trên môi trường .Net 4 với ngôn ngữ lập trình là C sharp. Sở dĩ, lựa chọn ngôn ngữ C sharp và môi trường .Net vì: - Tính phổ thông của C sharp và môi trường .Net: hiện nay C sharp là một trong ba ngôn ngữ lập trình phổ biến nhất thế giới với môi trường .Net dễ dàng cài đặt và phân phối phần mềm (tương tự như java runtime – jdk của ngôn ngữ Java). - Tính hỗ trợ lập trình viên đầu cuối: C sharp và .Net được phát triển bởi Microsoft nên đã có những hỗ trợ khá nhiều đối với những lập trình đầu cuối (những người viết trực tiếp ra sản phẩm phần mềm ứng dụng). Hỗ trợ này thể hiện qua việc triển khai lập trình nhanh chóng, dễ sửa lỗi, hỗ trợ các thư viện – API cũng như tính thống nhất – không phân tán do chỉ có Microsoft chịu trách nhiệm. Tính toán lưới Trang 3 Các kỹ thuật lập trình song song được tham khảo từ tài liệu tham khảo [1] và [2]. Trong đó, [1] đảm nhận về các quan điểm lý thuyết và [2] là những kỹ thuật lập trình song song. 2. Các kỹ thuật lập trình song song 2.1 Lập trình tác vụ 2.1.1 Cơ bản về tác vụ Tác vụ (task) là nền tảng cơ bản trong lập trình song song. Trong đó, mỗi tác vụ chứa các lệnh thực thi chương trình và mỗi tác vụ được cung cấp cho những nhân CPU đang trống. Việc điều phối tác vụ cho nhân CPU xử lý được thực hiện bởi bộ định thời mặc định trong .Net 4. using System; using System.Threading.Tasks; namespace Listing_04 { class Listing_04 { static void Main(string[] args) { string[] messages = { "First task", "Second task", "Third task", "Fourth task" }; foreach (string msg in messages) { Task myTask = new Task(obj => printMessage((string)obj), msg); myTask.Start(); } // wait for input before exiting Console.WriteLine("Main method complete. Press enter to finish."); Console.ReadLine(); } static void printMessage(string message) { Console.WriteLine("Message: {0}", message); } } } Ví dụ 2.1 : cơ bản tác vụ Ở ví dụ 2.1 để sử dụng được tác vụ thì cần khai báo tên miền: using System.Threading.Tasks; Kết quả đạt được là những “First Task”, “Third Task”, “Second Task” ngẫu nhiên không theo thứ tự. Vì bộ định thời sẽ quyết định những luồng (thread) cho tác vụ và Tính toán lưới Trang 4 mỗi luồng là khác nhau về thời gian xử lý nên kết quả đạt được mỗi lần chạy là khác nhau. Tác vụ cũng có thể được xem là một hàm có giá trị trả về. Task<int> task1 = Task.Factory.StartNew<int>(() => { int sum = 0; for (int i = 0; i < 100; i++) { sum += i; } return sum; }); Console.WriteLine("Result 1: {0}", task1.Result); Ví dụ 2.2: giá trị trả về của tác vụ 2.1.2 Thực hiện dừng tác vụ Dừng tác vụ được thực hiện bởi những cơ bản sau: - Tạo một thực thể mới của CancellationTokenSource để khai báo việc dừng tác vụ. - Tạo một token từ chối tác vụ CancellationToken. Token này để xác định dừng những tác vụ cụ thể. Token này được tạo ra thực thể của CancellationTokenSource. - Gán token cho tác vụ cần dừng. Task task1 = new Task(new Action(myMethod), token); - Sau khi khởi động tác vụ. Muốn dừng tác vụ thì từ thực thể của CancellationTokenSource sau đó là phương thức Cancel(). Từ những thao tác ở trên có thể dừng các tác vụ. Lợi điểm của phương pháp trên sử dụng một đối tượng khác Task để dừng tác vụ. Điều này giúp rõ ràng trong việc thực thi tác vụ. Vì tác vụ thực thi khó xác định tác vụ nào xử lý trước nên tách rời thao tác dừng tác vụ giúp rõ ràng cho lập trình viên. Đồng thời, có thể dừng một lúc nhiều tác vụ cùng nhau nếu các tác vụ ấy cùng thông qua một token. Trong vòng lặp sẽ thực hiện dừng vòng lặp khi token gọi Cancel() thông qua câu lệnh ThrowIfCancellationRequested() của token khi không có tài nguyên nào giải phóng. Nếu có tài nguyên cần giải phóng thì sử dụng câu lệnh token.IsCancellationRequested để kiểm tra trạng thái dừng của token và giải phóng các tài nguyên cần thiết. Ví dụ 2.3: bên dưới thể hiện dừng nhiều tác vụ cùng lúc. Tính toán lưới Trang 5 using System; using System.Threading; using System.Threading.Tasks; namespace Listing_10 { class Listing_10 { static void Main(string[] args) { CancellationTokenSource tokenSource = new CancellationTokenSource(); CancellationToken token = tokenSource.Token; Task task1 = new Task(() => { for (int i = 0; i < int.MaxValue; i++) { token.ThrowIfCancellationRequested(); Console.WriteLine("Task 1 - Int value {0}", i); } }, token); Task task2 = new Task(() => { for (int i = 0; i < int.MaxValue; i++) { token.ThrowIfCancellationRequested(); Console.WriteLine("Task 2 - Int value {0}", i); } }, token); Console.WriteLine("Press enter to start tasks"); Console.WriteLine("Press enter again to cancel tasks"); Console.ReadLine(); task1.Start(); task2.Start(); Console.ReadLine(); Console.WriteLine("Cancelling tasks"); tokenSource.Cancel(); Console.WriteLine("Main method complete. Press enter to finish."); Console.ReadLine(); } } } Ví dụ 2.3: Dừng nhiều tác vụ. Ngoài ra, để kiểm tra trạng thái tác vụ đang dừng hay chưa có thể dùng lệnh task.IsCanceled để kiểm tra trạng thái dừng. 2.1.3 Thực hiện chờ tác vụ Trong lập trình song song, do đa phần các tác vụ được thực hiện không theo trật tự nhất định (thực hiện song song hóa) nên cần phải có các thao tác chờ đợi tác vụ. Các vấn đề trong việc thực hiện chờ tác vụ bao gồm: Tính toán lưới Trang 6 - Chờ một tác vụ riêng rẽ: sử dụng phương thức Wait() của thực thể Task. Phương thức có thể cung cấp một thời gian chờ đợi tối đa và CancellationToken để dừng việc tác vụ. - Chờ đợi một tập các tác vụ: sử dụng phương thức tĩnh (static) Task.WaitForAll(). Phương thức sử dụng một mảng tác vụ cùng với việc cung cấp một thời gian chờ và CancellationToken để dừng tác vụ. - Chờ đợi tác vụ đầu tiên trong tập các tác vụ: sử dụng phương thức tĩnh Task.WaitAny(). Phương thức này tương tự như Task.WaitForAll() về cấu trúc. Ví dụ 2.4, bên dưới sẽ minh họa cách chờ một tác vụ riêng rẽ. using System; using System.Threading; using System.Threading.Tasks; namespace Listing_16 { class Listing_16 { static void Main(string[] args) { CancellationTokenSource tokenSource = new CancellationTokenSource(); CancellationToken token = tokenSource.Token; Task task = createTask(token); task.Start(); Console.WriteLine("Waiting for task to complete."); task.Wait(); Console.WriteLine("Task Completed."); task = createTask(token); task.Start(); Console.WriteLine("Waiting 2 secs for task to complete."); bool completed = task.Wait(2000); Console.WriteLine("Wait ended - task completed: {0}", completed); task = createTask(token); task.Start(); Console.WriteLine("Waiting 2 secs for task to complete."); completed = task.Wait(2000, token); Console.WriteLine("Wait ended - task completed: {0} task cancelled {1}", completed, task.IsCanceled); Console.WriteLine("Main method complete. Press enter to finish."); Console.ReadLine(); } static Task createTask(CancellationToken token) { return new Task(() => { for (int i = 0; i < 5; i++) { token.ThrowIfCancellationRequested(); Tính toán lưới Trang 7 Console.WriteLine("Task - Int value {0}", i); token.WaitHandle.WaitOne(1000); } }, token); } } } Ví dụ 2.4: chờ một tác vụ riêng rẽ. Ví dụ 2.5: minh họa chờ tác vụ đầu tiên trong tập các tác vụ. Sau khi chờ đợi tác vụ đầu tiên hoàn thành trong tập tác vụ task1, task2 sẽ thao tác tiếp mà không cần hoàn thành đủ 2 task trên. using System; using System.Threading; using System.Threading.Tasks; namespace Listing_18 { class Listing_18 { static void Main(string[] args) { // create the cancellation token source CancellationTokenSource tokenSource = new CancellationTokenSource(); // create the cancellation token CancellationToken token = tokenSource.Token; // create the tasks Task task1 = new Task(() => { for (int i = 0; i < 5; i++) { // check for task cancellation token.ThrowIfCancellationRequested(); // print out a message Console.WriteLine("Task 1 - Int value {0}", i); // put the task to sleep for 1 second token.WaitHandle.WaitOne(1000); } Console.WriteLine("Task 1 complete"); }, token); Task task2 = new Task(() => { Console.WriteLine("Task 2 complete"); }, token); // start the tasks task1.Start(); task2.Start(); // wait for the tasks Console.WriteLine("Waiting for tasks to complete."); int taskIndex = Task.WaitAny(task1, task2); Console.WriteLine("Task Completed. Index: {0}", taskIndex); // wait for input before exiting Console.WriteLine("Main method complete. Press enter to finish."); Tính toán lưới Trang 8 Console.ReadLine(); } } } Ví dụ 2.5: chờ tác vụ đầu tiên hoàn thành trong tập các tác vụ 2.1.4 Bắt ngoại lệ khi chạy tác vụ Ngoại lệ là những trường hợp lỗi phát sinh khi chạy chương trình trên .Net. Trong .Net cho phép lập trình viên thao tác trên những ngoại lệ để xử lý những trường khi xảy ra lỗi chương trình. Ngoại lệ có thể tự phát sinh hoặc được chủ động phát sinh như ở trường hợp ThrowIfCancellationRequested() ở phần dừng tác vụ. Ví dụ 2.6: minh họa bắt ngoại lệ khi chạy tác vụ. Trong đó, xử lý ngoại lệ được sử dụng trong một khối lệnh try…catch(). using System; using System.Threading.Tasks; namespace Listing_19 { class Listing_19 { static void Main(string[] args) { // create the tasks Task task1 = new Task(() => { ArgumentOutOfRangeException exception = new ArgumentOutOfRangeException(); exception.Source = "task1"; throw exception; }); Task task2 = new Task(() => { throw new NullReferenceException(); }); Task task3 = new Task(() => { Console.WriteLine("Hello from Task 3"); }); // start the tasks task1.Start(); task2.Start(); task3.Start(); // wait for all of the tasks to complete // and wrap the method in a try catch block try { Task.WaitAll(task1, task2, task3); } catch (AggregateException ex) { // enumerate the exceptions that have been aggregated foreach (Exception inner in ex.InnerExceptions) { Console.WriteLine("Exception type {0} from {1}", inner.GetType(), inner.Source); } } Tính toán lưới Trang 9 // wait for input before exiting Console.WriteLine("Main method complete. Press enter to finish."); Console.ReadLine(); } } } Ví dụ 2.6: xử lý ngoại lệ khi chạy tác vụ. 2.1.5 Các lỗi thường gặp và cách xử lý Các lỗi thường gặp khi lập trình song song cho tác vụ: - Lỗi deadlock: lỗi khi 2 hay nhiều tác vụ đợi lẫn nhau để hoàn thành tác vụ, điều đó chiếm giữ tài nguyên làm cho các tác vụ không sử dụng được tài nguyên và gây ra việc đợi vô thời hạn . Hạn chế lỗi deadlock bằng cách hạn chế tác vụ phụ thuộc lẫn nhau. - Lỗi biến cục bộ: lỗi nảy sinh khi dùng chung 1 biến giữa các task. Ví dụ 2.7 sẽ thể hiện rõ gồm 2 phần “bad” task và good task. Trong đó, “bad” task sẽ xuất trùng giá trị I ở mỗi task. Còn good task sẽ xuất mỗi task là một giá trị riêng biệt. using System; using System.Threading.Tasks; namespace Local_Variable_Evaluation { class Local_Variable_Evaluation { static void Main(string[] args) { // create and start the "bad" tasks for (int i = 0; i < 5; i++) { Task.Factory.StartNew(() => { // write out a message that uses the loop counter Console.WriteLine("Task {0} has counter value: {1}", Task.CurrentId, i); }); } // create and start the "good" tasks for (int i = 0; i < 5; i++) { Task.Factory.StartNew((stateObj) => { // cast the state object to an int int loopValue = (int)stateObj; // write out a message that uses the loop counter Console.WriteLine("Task {0} has counter value: {1}", Task.CurrentId, loopValue); }, i); Tính toán lưới Trang 10 [...]... đ c biệt dùng để điều hướng t c vụ truy c p vào Critical Region để chia sẻ dữ liệu giữa c c tiến trình Tính toán lưới Trang 11 C c bư c cơ bản đồng bộ hóa t c vụ: - T c vụ sẽ kiểm tra Synchronization Primitives để biết vùng Critical Region - đang bị chiếm giữ bởi c c t c vụ hay chưa Nếu chưa thi Critical Region sẽ đư c cấp phát cho t c vụ để th c thi c u lệnh Ngư c lại, khi Critical Region đang bị chiếm... qua 2 phương th c Break() và Stop() tương tự như lệnh break và stop Tuy nhiên, khi dừng Break() và Stop() những t c vụ đã bắt đầu thì sẽ đư c tiếp t c cho đến khi kết th c, chỉ tạm dừng và dừng hẳn vi c th c thi c c t c vụ mới 3 Kết luận Lập trình song song trên C sharp và Net 4 không chú trọng đi sâu c ch th c lập trình song song như thế nào mà chú trọng tập trung vi c cung c p cho lập trình viên những... lớp cung c p c c lớp đối tượng an toàn dùng để th c hiện đồng bộ hóa c c t c vụ thông qua c c t c vụ c tính chất lightweight Trong đó, c c cấu tr c dữ liệu chính: - System.Threading.Tasks.ConcurrentQueue: tương đương c u tr c Queue (hàng - đợi), tính chất vào trư c ra trư c (First In First Out) System.Threading.Tasks.ConcurrentStack: tương đương c u tr c Stack (ngăn - xếp), tính chất vào trư c ra... thường, c c lập trình viên c gắng tránh để xảy ra vấn đề chia sẻ dữ liệu tr c tiếp giữa c c t c vụ vì làm giảm hiệu năng tính toán khi song song hóa Đồng thời, đây là một lỗi logic khó đư c phát hiện khi th c thi chương trình Tuy nhiên, nếu bắt bu c gặp phải trường hợp chia sẻ dữ liệu giữa c c t c vụ thì Net 4 và C sharp c ng cung c p những phương th c để xử lý nhanh chóng đối với c c lập trình viên... finish"); Console.ReadLine(); } } } - Ví dụ 2.8: sử dụng lock để chia sẻ dữ liệu Sử dụng toán tử Interlocked: toán tử Interlocked c ch th c hoạt động c ng giống như lock như đư c tối ưu cho hệ điều hành và c hiệu năng cao hơn trong tính toán (đư c cung c p bởi Microsoft) C c phương th c trong Interlocked là c c phương th c tĩnh và đư c dùng nhiều cho đồng bộ hóa t c vụ Kiểu dữ liệu thường đư c dùng cho... before exiting Console.WriteLine("Main method complete Press enter to finish."); Console.ReadLine(); } Ví dụ 2.7: lỗi biến c c bộ 2.2 Chia sẻ dữ liệu Chia sẻ dữ liệu giữa c c t c vụ trong lập trình song song là một vấn đề khó khăn và ph c tạp Vậy tại sao c n phải chia sẻ dữ liệu giữa c c t c vụ mà không th c thi nhưng bình thường Vấn đề khi lập trình song song nếu dữ liệu đư c chia sẻ cho t c vụ không... 2.4 Vòng lặp song song Bên c nh những c u lệnh vòng lặp truyền thống (for, foreach, while, do…while) Để tối ưu cho vi c song song, C sharp c n cung c p c u lệnh vòng lặp dành cho lập trình song song, đó là For và Foreach Ví dụ 2.16 và ví dụ 2.17 là hai ví dụ minh họa vòng lặp song song for và foreach using System; using System.Threading.Tasks; namespace Listing_03 { class Listing_03 { static void Main(string[]... Đồng bộ hóa t c vụ Đồng bộ hóa t c vụ c bản là điều chỉnh c c lại t c vụ để th c hiện 2 khái niệm c bản trong đồng bộ hóa t c vụ đó là Critical Region và Synchronization Primitives - Critical Region: là khối lệnh chứa một ho c nhiều c u lệnh dùng để tránh vi c - tranh chấp dữ liệu Ví dụ for (int j = 0; j < 1000; j++) { account.Balance = account.Balance + 1; // < critical region } Synchronization... c c t c vụ con hoàn thành rồi t c vụ cha mới - hoàn thành T c vụ cha sẽ phát sinh lỗi và t c vụ con xử lý lỗi T c vụ cha c trạng thái phụ thu c vào trạng thái c a t c vụ con Tính toán lưới Trang 20 Khai báo đơn giản để biết t c vụ con c liên quan đến t c vụ cha dùng phương th c tĩnh TaskCreationOptions.AttachedToParent() using System; using System.Threading; using System.Threading.Tasks; namespace... đ c dữ liệu (reader lock) chia sẻ dữ liệu giữa nhiều t c vụ và hai dùng để ghi dữ liệu (writer lock) khi c sự thay đổi dữ liệu Khi writer lock đư c th c thi thì c c reader lock sẽ đư c giải phóng để truy xuất vào Critical Region Tính toán lưới Trang 15 Môi trường Net 4 hỗ trợ lớp System.Threading.ReaderWriterLockSlim dành cho Reader và Writer lock Đây là những lock thu c dạng lightweight và đư c Microsoft . Th c hiện chờ t c vụ Trong lập trình song song, do đa phần c c t c vụ đư c th c hiện không theo trật tự nhất định (th c hiện song song hóa) nên c n phải c c c thao t c chờ đợi t c vụ. C c vấn. trình song song 2.1 Lập trình t c vụ 2.1.1 C bản về t c vụ T c vụ (task) là nền tảng c bản trong lập trình song song. Trong đó, mỗi t c vụ chứa c c lệnh th c thi chương trình và mỗi t c vụ. giữa c c t c vụ thì .Net 4 và C sharp c ng cung c p những phương th c để xử lý nhanh chóng đối với c c lập trình viên. 2.2.1 Đồng bộ hóa t c vụ Đồng bộ hóa t c vụ c bản là điều chỉnh c c lại

Ngày đăng: 09/04/2015, 16:15