2.3.1 Linux
Giới thiệu về hệ điều hành linux
Linux là hệ điều hành mã mở. Ngay từ khi mới xuất hiện, nó đã nhanh chóng được biết tới như là một hệ điều hành UNIX với mã nguồn mở. Nó là sự tái chế lại của một trong những hệ điều hành lâu đời nhất và hiện nay được sử dụng rộng rãi- hệ điều hành UNIX. Linux bao gồm công nghệ cũ và mới.
Linux có thể cài đặt trên máy tính cá nhân và trở thành một trạm làm việc với đầy đủ sức mạnh của Unix. Linux cũng có thể được sử dụng vào mục đích thương mại trên một mạng máy tính như một môi trường tính toán và truyền tin. Trong các trường đại học, Linux được sử dụng để giảng dạy về hệ điều hành và lập trình hệ điều hành. Và tất nhiên, Linux cũng có thể được sử dụng trên các máy tính cá nhân như các hệ điều hành khác.
Ngoài chức năng trạm làm việc và người sử dụng đơn lẻ, Linux còn được sử dụng trên các máy chủ lớn. Linux ngày càng tỏ ra là một hệ điều hành mạnh, ổn định và đủ mềm dẻo để chạy trên các hệ thống với bộ nhớ lớn và đa xử lý. Linux
còn được sử dụng để nối ghép nhiều máy tính với nhau tạo thành các “cluster” rất mạnh để giải quyết các nhu cầu tính toán hiệu năng cao. Đây là vấn đề được đề cập đến trong khóa luận.
Lịch sử của hệ điều hành Linux
Linux bắt nguồn từ hệ điều hành lớn là Unix, Unix được sử dụng rộng rãi nhất trên thế giới do tính ổn định và khả năng hỗ trợ của nó. Linux là phiên bản cung cấp miễn phí, ban đầu được phát triển bởi Linus Torvald năm 1991 khi còn là một sinh viên của trường đại học Helssinki Phần Lan. Khi Linux tung ra phiên bản đầu tiên(0.02) trên Internet, nó đã tạo ra một làn sóng phát triển phần mềm lớn trên phạm vi toàn cầu. Hiện nay, Linux được phát triển và bảo trì bởi hàng nghìn lập trình viên cộng tác chặt chẽ với nhau qua Internet. Nhiều công ty đã xuất hiện, cung cấp Linux dưới dạng gói phần mềm dễ cài đặt, hoặc cung cấp các máy tính đã cài đặt sẵn Linux.
Hiện nay, Linux là một hệ điều hành Unix đầy đủ và độc lập. Nó có thể chạy X Window, TCP/IP,Emacs,Web, thư điện tử và các phần mềm khác. Hầu hết các phần mềm miễn phí và thương mại đều được chuyển lên Linux. Rất nhiều nhà phát triển phần mềm đã chuyển sang viết trên Linux. Người ta đã thực hiện các phép đo benchmarks trên các hệ Linux và thấy rằng chúng thực hiện nhanh hơn khi thực hiện trên các trạm làm việc Sun Microsystems và Compaq, thậm chí nhiều khi còn nhanh hơn cả trên Windows 98 và Windows NT.
Tại sao dùng Linux ?
Nếu bạn có một máy tính trong tay, đầu tiên bạn phải có một hệ điều hành cài đặt để chạy các trình ứng dụng. Hệ điều hành là chương trình điều hành mọi hoạt động trong máy tính của bạn, mọi chương trình ứng dụng khác đều phải chạy trên hệ điều hành này. Linux là hệ điều hành mã nguồn mở, được cung cấp miễn phí cho người sử dụng. Nó có khả năng đa nhiệm, đa xử lý, hỗ trợ mạng, khả năng tương thích phần cứng và nhiều tính năng khác. Sau đây là các tính năng mà bạn có trong hệ điều hành Linux:
Tính ổn định: Linux có tính ổn định cao, đây là một trong những ưu điểm của
dụng so với hầu hết các hệ điều hành khác. Người sử dụng Linux sẽ không phải lo lắng đến chuyện máy tính của mình bị hiện tượng “treo cứng” khi đang sử dụng. Thông thường lý do để bạn bắt buộc phải khởi động lại hệ thống là do mất điện, nâng cấp phần cứng và phần mềm.
Tính bảo mật: Khi làm việc trên Linux, người dùng có thể yên tâm hơn về
tính bảo mật của hệ điều hành. Linux là hệ điều hành đa nhiệm, đa người dùng, điều này có nghĩa là người dùng có thể vào phiên làm việc của mình trên cùng một máy tại cùng một thời điểm. Linux cung cấp các mức bảo mật khác nhau cho người sử dụng. Một người sử dụng chỉ làm việc trên một không gian tài nguyên dành riêng, chỉ có người quản trị hệ thống mới có quyền thay đổi trong máy.
Tính hoàn chỉnh: Bản thân Linux đã được kèm theo các trình tiện ích cần thiết. Tất cả các trình tiện ích mà bạn mong đợi đều có sẵn hoặc ở một dạng tương đương rất giống. Trên Linux, các trình biên dịch như C,C++.. các hạt nhân hay TCP/IP đều được chuẩn hóa.
Tính tương thích: Linux tương thích hầu như hoàn toàn các chuẩn Unix như IEEE POSIX.1, Unix System V, và BSD Unix. Trên Linux bạn có thể tìm thấy các trình giả lập của DOS và Windows cho phép bạn có thể chạy các ứng dụng quen thuộc trên DOS và Windows. Linux cũng hổ trợ hầu hết các phần cứng máy PC.
Linux là hệ điều hành 32 bit hay 64 bít đầy đủ: Ngay từ đầu Linux đã là hệ điều hành 32 bít đầy đủ. Điều đó có nghĩ là không phải lo về giới hạn bộ nhớ.
Lập trình song song trên Linux
Linux cung cấp một gói phần mềm(package) hỗ trợ cho lập trình song song. Gói(package) hỗ trợ lập trình song song không được cài mặt định, vì vậy trong quá trình cài đặt chúng ta phải vào chế độ custom và chọn Software Development và Science, chú ý là phải xem xét chi tiết các gói cụ thể để chọn lựa, ngoài ra các phiên bản cũ hơn không có package này (từ Redhat Linux 7.3 trở lên có hỗ trợ gói này). Ở đây chúng ta dùng bản Linux Redhat 10.
Thư viện lập trình song song LAM (Local Area Multicomputer) của Linux là hiện thực của chuẩn lập trình truyền thông điệp (MPI-Message Passing Interface).
Các bước để chạy và biên dịch chương trình:
1. Tạo một tập tin schema (ví dụ lamhosts) chứa tên máy (hoặc địa chỉ IP) trong mạng mà chương trính song song sẽ chạy trên đó. Nếu dùng một máy đơn thì lamhosts sẽ có nội dung như sau:
127.0.0.1
2. Khởi động LAM cho các máy: lamboot –v lamhosts
Không nên khởi động LAM từ root 3. Biên dịch chương trình
hcc -o tinhtong tinhtong.c
(tinhtong.c giả sử là mã nguồn của chương trình song song) 4. Thực thi chương trình song song:
mpirun -v -c n tinhtong
Trong đó n là số các tiến trình cần khởi tạo để chạy tinhtong
Để minh họa việc thực thi một chương trinh song song có thể xem minh họa sau:
Hình 2.8 Lập trình song song trên Linux
2.3.2 Windows
Trong Linux việc viết và chạy chương trình song song rất dễ dàng, nhưng việc thiết lập một mạng các máy tính Linux có một số khó khăn. Do đó chúng ta có thể dùng mã nguồn chương trình đã xây dựng trong Linux rồi biên dịch lại trong windows và sử dụng tiện ích MPICH để chạy chương trình song song. Lúc này chúng ta sử dụng một mạng các máy tính cài đặt hệ điều hành windows, vì hiện nay hầu hết các mạng máy tính thường là dùng hệ điều hành windows.
Các bước lập trình song song trên windows và thực thi chương trình song song: 1. Tải MPICH tại www.lammpi.org có tên mpich.nt.1.2.5.zip
2. Tiến hành giải nén và cài đặt
3. Copy các thư viện tại vị trí C:\Program Files\MPICH\SDK\Lib vào C:\Program Files\Microsoft Visual Studio\VC98\Lib
4 . Mở MS Developer Studio – Visual C++ 5. Tạo một project mới
Hình 2.9 Thiết lập tham số
7 Viết chương trình trong VC++ rồi biên dịch sang dạng exe 8 Một cách đơn giản để chạy chương trình song song:
Copy chương trình(file chương trình exe ví dụ là tinhtong.exe ở thư mục debug của project của chương trình này và chương trình mpirun.exe ở thư mục C:\Program Files\MPICH\mpd\bin vào c:\ rồi thực hiện các bước như hình sau:
Hình 2.10 Chạy chương trình trên Windows
Để có thể nối mạng nhiều máy tính với nhau để chạy chương trình song song
Giả sử ở đây chúng ta cần 2 máy, đầu tiên tạo cho 2 máy, mỗi máy một tài khoản với quyền administrator ví dụ account: mpi ,password: 123456
Cài MPICH vào mỗi máy, dùng một thư mục chia sẻ dùng chung cho 2 máy. Cấu hình kết nối các máy:
-Chạy C:\Program Files\MPICH\mpd\bin\mpiconfig
-Chọn các máy để chạy chương trình song song. Nhấn apply rồi ok Chạy chương trình song song
Hình 2.11Chạy chương trình Khử Gaus trên hai máy tính với windows
Chương IIIKỹ thuật đường ống và cân bằng tải trong lập trình song song
3.1 Cân bằng tải tập trung trong bài toán tìm đường đi ngắn nhất với giải thuật Moore thuật Moore
Cân bằng tải
Khi chia một bài toán vào một số cố định các tiến trình để thực hiện song song thì mỗi tiến trình sẽ biết trước được số lượng công việc cần làm. Thêm vào đó, giả sử rằng các tiến trình được phân bố vào các bộ xử lý mà không có bất kỳ thảo luận nào về tác dụng của các loại bộ xử lý cũng như tốc độ của chúng. Khi đó, có thể một số bộ xử lý sẽ hoàn thành các tác vụ của chúng trước các bộ xử lý khác và trở nên nhàn rỗi bởi vì các công việc được phân chia không bằng nhau hoặc các bộ xử lý tính toán nhanh hơn bộ xử lý khác (hoặc cả hai tình huống). Với ý tưởng đó, chúng ta mong muốn tất cả các bộ xử lý thực hiện liên tục trên các tác vụ để đạt được thời gian thực hiện nhỏ nhất. Để đạt được điều này thì chúng ta phân bố các tác vụ bằng nhau trên các bộ xử lý gọi là cân bằng tải.
Cân bằng tải động
Trong cân bằng tải động, các tác vụ được truyền đến các bộ xử lý trong suốt quá trình thực hiện của chương trình. Cân bằng tải động có hai loại:
- Cân bằng tải động tập trung
- Cân bằng tải động không tập trung
Trong cân bằng tải động tập trung, các tác vụ được thực hiện từ một vị trí tập trung. Sử dụng cấu trúc master-slave (chủ-tớ), tiến trình chủ điều khiển một tập các tiến trình tớ một cách trực tiếp. Ngược lại, cân bằng tải động không tập trung các tác vụ được thực hiện giữa các tiến trình bất kỳ. Một tập hợp các tiểu trình tính toán trên bài toán và tương tác của chúng được gởi đến một tiến trình đơn. Một tiểu trình có thể nhận hoặc gởi nhiệm vụ đến các tiểu trình khác.
Cân bằng tải động tập trung.
Tiến trình chủ quản lý một tập hợp các tác vụ để thực hiện. Các tác vụ được gởi đến các tiến trình tớ. Khi một tiến trình tớ hoàn thành một tác vụ, nó yêu cầu tác vụ
Kỹ thuật phân chia công việc có thể dễ dàng áp dụng cho các bài toán chia để trị đơn giản. Cũng có thể áp dụng cho các bài toán có tác vụ khác nhau và kích cỡ khác nhau. Nhìn chung kỹ thuật này thực hiện tốt cho các tác vụ lớn và phức tạp. Nếu tiến trình lớn đang thực hiện thì tiến trình nhỏ sẽ hoàn thành trước, sau đó đợi tiến trình lớn hoàn thành.
Kỹ thuật phân chia công việc cũng dễ dàng áp dụng khi số tiến trình có thể thay đổi trong suốt quá trình thực hiện của chương trình. Trong một số các thuật toán, đặc biệt là thuật toán tìm kiếm, khi thực hiện tác vụ này có thể phát sinh tác vụ khác, nhưng cuối cùng số tác vụ phải giảm xuống bằng không khi đó việc tính toán mới hoàn tất. Hàng đợi được sử dụng để quản lý các tác vụ, như hình 3.1. Nếu tất cả các tác vụ có kích cỡ và tính cấp thiết giống nhau thì có thể tạo ra một hàng đợi vào trước ra trước (FIFO) đơn giản. Nếu một số tác vụ quan trọng hơn tác vụ khác (ví dụ như cần đưa ra một giải pháp một cách nhanh chóng) thì khi đó những tác vụ này sẽ được gởi đến các tiến trình tớ đầu tiên.
Tìm đường đi ngắn nhất:
Chúng ta sẽ nghiên cứu tỉ mỉ bài toán tìm khoảng cách ngắn nhất giữa hai điểm trong một đồ thị. Nó có thể phát biểu như sau:
Cho một tập các node kết nối với nhau ở đây các đường kết nối giữa các node có trọng số, tìm đường đi từ một node đặc biệt đến các node đặc biệt khác mà có đường đi với trọng số nhỏ nhất.
Phân chia công việc
Hàng đợi Các tác vụ Tiến trình chủ Các tiến trình tớ Gởi tác vụ Yêu cầu tác vụ (và có thể đưa ra các tác vụ mới)
Các node kết nối với nhau có thể được mô tả bởi một đồ thị. Trong thuật ngữ đồ thị, các node được gọi là các đỉnh và các liên kết gọi là các cạnh nếu một cạnh đi theo một hướng, đồ thị là đồ thị định hướng. Bài toán bây giờ là tìm một đường đi tốt nhất thông qua đồ thị. Đồ thị có thể được sử dụng trong các lời giải với những vấn đề khác nhau như:
Tìm đường đi ngắn nhất giữa hai thành phố hoặc hai điểm của một bản đồ, ở đây trọng số miêu tả khoảng cách.
Lộ trình nhanh nhất để đi du lịch, ở đây trọng số miêu tả thời gian.
Chi phí ít nhất để đi du lịch bằng máy bay, ở đây trọng số miêu tả giá trị của chuyến bay giữa các thành phố.
Cách tốt nhất để để leo một ngọn núi căn cứ vào một bản đồ địa hình với những đường chỉ dẫn.
v.v
Leo lên một ngọn đồi sẽ được sử dụng để minh họa. Ở đây trọng số được xác định là số lượng những nỗ lực trải qua giữa hai điểm cắm trại được kết nối với nhau. Chú ý đồ thị ở đây là đồ thị có hướng. Bởi vì nỗ lực để lên đỉnh đồi sẽ khác với nỗ lực để xuống đồi.
Hình 3.2 Leo một ngọn đồi
Hình 3.3 Đồ thị của leo đồi
1.Matrận kề, một mảng hai chiều a, trong đó a[i][j] nắm trọng số kết nối giữa đỉnh i với đỉnh j nếu tồn tại liên kết.
2. Danh sách kề, với mỗi đỉnh, một danh sách các đỉnh được kết nối trực tiếp với đỉnh bởi cạnh và có trọng số tương ứng kết hợp với cạnh.
Hai phương pháp này có thể mô tả như hình sau:
Ma trận kề
Danh sách kề
Tìm kiếm một đồ thị
Có hai thuật toán tìm đường đi ngắn nhất để xác định cách tốt nhất đến đỉnh núi:
Moore, 1957 Dijkstra, 1959
Hai thuật toán này là tương tự nhau, thuật toán Moore được chọn bởi vì nó tuân thủ thực thi song song nhiều hơn, mặc dù nó có lẽ làm nhiều việc hơn.
Thuật toán Moore: Bắt đầu từ một đỉnh nguồn, thuật toán thi hành khi đỉnh i được xem xét như sau: tìm khoảng cách từ đỉnh j đến i và so sánh với khoảng cách nhỏ nhất hiện tại đến j. Thay đổi khoảng cách nhỏ nhất hiện tại nếu khoảng cách từ i đến là ngắn hơn. Gọi di là khoảng cách nhỏ nhất hiện tại từ đỉnh nguồn đến đỉnh i, và wi,j là trọng số của cạnh từ đỉnh i đến đỉnh j, ta có:
dj= min(dj,di+wi,j)
Một hàng đợi các đỉnh với phương thức vào trước ra trước được tạo và nắm lấy danh sách các đỉnh để xem xét. Những đỉnh được xem xét chỉ khi chúng nằm trong hàng đợi. Khi khởi tạo, chỉ đỉnh nguồn nằm trong hàng đợi. Giả sử có n đỉnh, và đỉnh 0 là đỉnh nguồn. Khoảng cách ngắn nhất hiện tại từ đỉnh nguồn đến đỉnh i sẽ được lưu trong mảng dist[i] (1<=i<=n). Đầu tiên mảng dist[i] được khởi tạo là vô cùng. Giả sử w[i][j] nắm trọng số của cạnh từ đỉnh i và đỉnh j. Đoạn code như sau:
newdist_j=dist[i]+w[i][j];
if(newdist_j<dist[j]) dist[j]=newdist_j;
Khi khoảng cách nhỏ nhất được tìm thấy đến đỉnh j, đỉnh j được thêm vào hàng đợi (nếu nó không thực sự nằm trong hàng đợi).
Chi tiết của quá trình xử lý như sau ( giả sử ta sử dụng đồ thị leo đồi để minh họa) Giá trị khởi tạo cho hàng đợi và mảng trọng số lúc đầu là:
Phần tử dist[a] luôn là 0 khi đỉnh a là nguồn, nhưng có thể tổng quát lên khi a được thay thế bằng một đỉnh nguồn khác. Đầu tiên, mỗi cạnh bắt nguồn từ a là được xem