Nó sử dụng các công thức biểu diễn sự liên quan của fault và failure, đến môi trường hoạt động của phần mềm như hệ điều hành, dữ liệu của phần mềm… 1.2.5 - Biện pháp xây dựng phần mềm ch
Trang 1MỞ ĐẦU
Từ mấy thập kỷ nay, các hệ thống máy tính đã được ứng dụng trong rất nhiều lĩnh vực đời sống xã hội, nhiều các ngành công nghiệp phụ thuộc rất nhiều vào các hệ thống máy tính trong quá trình hoạt động của mình Sự an toàn và tính tin cậy trong hoạt động của các hệ thống phần mềm là yêu cầu cơ bản và quan trọng nhất trong nhiều lĩnh vực công nghiệp có ứng dụng công nghệ thông tin, chẳng hạn các ngành công nghiệp như công nghiệp hàng không, công nghiệp dầu lửa, các hoạt động thương mại điện tử, ngân hàng điện tử, công nghiệp tự động hoá, các hệ thống phục vụ trong lĩnh vực quốc phòng, lĩnh vực nghiên cứu không gian, công nghiệp sản xuất hàng gia dụng (sản xuất máy giặt, sản xuất ôtô…) Cùng với sự phát triển của khoa học công nghệ thì nhu cầu giải các bài toán trên các phần cứng có hiệu năng tính toán cao và phần mềm chất lượng ngày càng trở nên quan trọng.[4]
Trong một số trường hợp, nếu hệ thống máy tính hoạt động không bình thường sẽ là nguyên nhân xảy ra các tai nạn thảm khốc, khó lường trước được hậu quả, gây thiệt hại lớn về người cũng như về tài sản Bên cạnh phần cứng, trong các hệ thống máy tính, phần mềm chiếm vị trí vô cùng quan trọng đảm bảo cho hệ thống hoạt động một cách bình thường.[10]
Kích cỡ và độ phức tạp của các hệ thống thông tin liên tục phát triển với một tốc độ chóng mặt trong những năm 90 của thế kỷ trước và xu hướng vẫn đó vẫn tiếp tục trong tương lai là điều tất yếu Hiện nay có rất nhiều ứng dụng với số lượng mã nguồn lên đến hàng triệu dòng [9] Do đó việc phát sinh ra lỗi phần mềm trong quá trình hoạt động rất dễ xảy ra và trong thực tế cho dù
có được xây dụng một cách cẩn thận bởi những nhóm lập trình chuyên nghiệp nhất thì phần mềm vẫn không thể không có lỗi.[2]
Vấn đề đặt ra ở đây là làm sao để nâng cao độ tin cậy nhằm làm giảm bớt các
Trang 2mềm là xác suất không xảy ra lỗi khi phần mềm hoạt động trong một khoảng thời gian nào đó trong một môi trường cụ thể Để giải quyết một phần vấn đề đặt trên, luận văn này chọn nghiên cứu đề tài “Đánh giá và so sánh các kỹ thuật xây dựng phần mềm chịu lỗi” Nội dung của luận văn bao gồm những phần sau:
Chương 1: Tổng quát về kỹ thuật xây dựng phần mềm chịu lỗi Chương này trình bày một số khái niệm và các phương pháp chung trong xây dựng phần mềm chịu lỗi
Chương 2: Trình bày các phương pháp xây dựng phần mềm chịu lỗi bao gồm hai nhóm kỹ thuật là nhóm các kỹ thuật đa thiết kế và nhóm các kỹ thuật đa dữ liệu Ngoài ra chương này cũng tìm hiều một số phương pháp đánh giá kết quả
Chương 3: Đánh giá, so sánh hiệu quả hoạt động giữa các kỹ thuật xây dựng phần mềm chịu lỗi với nhau và trình bày một số kỹ thuật xây dựng phần mềm chịu lỗi khác được thiết kế dựa trên cơ sở những kỹ thuật cơ bản trước đó
Chương 4: Trình bày một số bài toán áp dụng cho các kỹ thuật xây dựng phần mềm chịu lỗi giúp hiểu thấu đáo hơn sự hoạt động cũng như tính hiệu quả của từng kỹ thuật xây dựng phần mềm chịu lỗi đối với các hệ thống phần mềm
Cuối cùng là một số kết luận trong xây dựng phần mềm chịu lỗi và các vấn đề cần quan tâm nghiên cứu ở các giai đoạn nghiên cứu tiếp theo
Trang 3Chương 1 - TỔNG QUÁT VỀ KỸ THUẬT XÂY DỰNG PHẦN MỀM
CHỊU LỖI
1.1 - Xây dựng phần mềm và các vấn đề gặp phải
Như trên đã nói, việc xây dựng phần mềm khó tránh khỏi lỗi xảy ra trong quá trình hoạt động Cho dù phần mềm đó được thiết kế và phát triển bởi các nhà khoa học, các nhà lập trình suất sắc nhất và được sử dụng các công cụ trợ giúp hiện đại nhất thì cũng không thể nói rằng phần mềm không có lỗi Thêm nữa, tăng cường tính tin cậy của phần mềm là một thách thức rất lớn nếu so sánh với việc làm đó đối với phần cứng Thông thường lỗi phần cứng là các lỗi vật lý mà con người có thể biết rõ đặc điểm hoặc có thể nhận biết trước được lỗi phần cứng khi nó xảy ra Trái lại, lỗi phần mềm không là lỗi vật lý,
nó không bị cháy, nổ hoặc méo mó như phần cứng, nó rất khó để nhìn thấy, nhận thức được và quan trọng nhất là rất khó để khắc phục lỗi phần mềm Lỗi phần mềm xảy ra trong nhiều trường hợp khác nhau, có thể phần mềm được xây dựng theo đúng yêu cầu đặt ra nhưng bản thân yêu cầu đó đã được hiểu sai so với bài toán thực tế, cũng có thể phần mềm được thiết kế và phát triển sai so với yêu cầu Có một điều cần lưu ý rằng, không giống như lỗi do phần cứng, đối với lỗi phần mềm quá trình thay đổi hoặc sửa chữa lỗi phần mềm có thể sinh ra các lỗi mới khác Để khắc phục phần mềm có lỗi không chỉ đơn giản như phần cứng (thay thế phần cứng khác), vì việc này có thể làm phần mềm càng bị lỗi nhiều hơn Để giải quyết vấn đề này buộc người ta phải nghĩ đến việc nghiên cứu các giải pháp kỹ thuật để phục vụ cho việc xây dựng phần mềm có khả năng chịu được lỗi [2]
Trang 41.2 - Các biện pháp để nâng cao tính tin cậy của phần mềm
1.2.1 - Một số khái niệm
Trước hết tìm hiểu một số khái niệm thường được sử dụng khi nói đến quá trình hoạt động của phần mềm bất kỳ Khái niệm đầu tiên nói đến ở đây là fault, đó chính là sự thiếu sót, sự sai lầm mắc phải trong quá trình xây dựng phần mềm, nó chính là nguyên nhân gây ra lỗi khi phần mềm hoạt động
Error là một trạng thái lỗi được xác định của phần mềm Error có thể là nguyên nhân gây ra các error khác Các fault cũng sẽ được nhận diện khi có một error nào đó xảy ra
Tiếp theo là khái niệm failue, nó xảy ra khi phần mềm thực hiện hành động khác không thuộc trong các hành động nằm trong dự định của nhà thiết kế khi thiết kế phần mềm
Trong thực tế các khái niệm trên có liên quan với nhau thanh một vòng tròn, cái này là nguyên nhân của cái kia, cái kia là hậu quả của cái này
Các biện pháp để nâng cao tính tin cậy của phần mềm được chia thành hai nhóm chính, nhóm thứ nhất áp dụng trong quá trình xây dựng phần mềm (biện pháp tránh lỗi và biện pháp xây dựng phần mềm chịu lỗi) Nhóm thứ hai được áp dụng sau khi phần mềm đã được xây dựng xong (biện pháp loại bỏ lỗi và biện pháp dự đoán lỗi) Tóm lại có các biện pháp sau được áp dụng để nâng cao tính tin cậy của phần mềm:
Biện pháp tránh lỗi
Biện pháp loại bỏ lỗi
Biện pháp dự đoán lỗi
Biện pháp xây dựng phần mềm chịu lỗi
1.2.2 - Biện pháp tránh lỗi
Biện pháp này được thực hiện trong quá trình xây dựng phần mềm nhằm giảm bớt lỗi xảy ra sau này khi phần mềm hoạt động Nó góp phần xây dựng phần
Trang 5mềm tin cậy hơn thông qua các giai đoạn xây dựng phần mềm, bắt đầu từ thiết lập các yêu cầu kỹ thuật của phần mềm, cho đến khi thiết kế kiến trúc, lựa chọn các phương pháp lập trình phù hợp, lựa chọn ngôn ngữ lập trình, các công cụ trợ giúp phát triển phần mềm
Trong mỗi giai đoạn phát triển phần mềm đếu phải có những yêu cầu đòi hỏi phải được tuân thủ Chẳng hạn giai đoạn xây dựng yêu cầu bắt buộc phải bám sát bài toán Trong thực tế, thông thường việc xây dựng phần mềm do các kỹ
sư phần mềm đảm nhiệm, họ không phải là người nắm vững hệ thống hiện tại,
do đó sai sót ở giai đoạn này rất dễ xảy ra
1.2.3 - Biện pháp loại bỏ lỗi
Biện pháp này được thực hiện tại giai đoạn kiểm tra, kiểm soát phần mềm sau khi nó đã được phát triển Nó tiến hành tìm kiếm các lỗi vẫn còn tồn tại thông qua các phương pháp kiểm tra, kiểm soát rồi sau đó tìm cách loại bỏ chúng ra khỏi hệ thống Một số biện pháp được sử dụng để loại bỏ lỗi phần mềm như biện pháp kiểm thử (testing) phần mềm, biện pháp kiểm tra lại mã nguồn của phần mềm
1.2.4 - Biện pháp dự đoán lỗi
Biện pháp này được sử dụng trong khi kiểm tra lại phần mềm sau khi được phát triển để dự đoán các lỗi của phần mềm có thể xảy ra trong quá trình hoạt động Việc thực hiện biện pháp này dựa trên độ đo tính tin cậy của phần mềm
Nó sử dụng các công thức biểu diễn sự liên quan của fault và failure, đến môi trường hoạt động của phần mềm như hệ điều hành, dữ liệu của phần mềm…
1.2.5 - Biện pháp xây dựng phần mềm chịu lỗi
Có một cách để giảm bớt tính rủi ro trong quá trình thiết kế phần mềm, do đó tăng cường tính ổn định của phần mềm đó là sử dụng các kỹ thuật xây dựng phần mềm có khả năng chịu lỗi Với việc sử dụng các kỹ thuật này, khi có lỗi xảy ra trong hệ thống, nó sẽ cung cấp cho hệ thống các cơ chế chịu đựng được
Trang 6lỗi của hệ thống Trong thực tế các kỹ thuật như vậy đã được nhắc đến và nghiên cứu từ trên 20 năm nay Hiện nay tồn tại rất nhiều kỹ thuật xây dựng phần mềm chịu lỗi được chia thành các nhóm như sau:[8]
Nhóm các kỹ thuật sử dụng một phiên bản phần mềm (Single Version Software): Đây là các kỹ thuật cổ điển, luôn được áp dụng trong khi phát triển bất kỳ phần mềm nào, ví dụ như kỹ thuật bắt lỗi,
kỹ thuật quản lý ngoại lệ (exception handling)…
Nhóm các kỹ thuật sử dụng nhiều phiên bản phần mềm (Multiple Version Software): Các kỹ thuật này sử dụng nhiều phiên bản phần mềm được thiết kế khác nhau cùng thực hiện một công việc của bài toán
Nhóm các kỹ thuật sử dụng nhiều dữ liệu làm đầu vào cho phần mềm (Multi Data): Các kỹ thuật này sử dụng cách biến đổi từ một
dữ liệu đầu vào duy nhất để cung cấp cho hệ thống, nhằm hy vọng rằng một trong số những dữ liệu đầu vào sau khi đã được biến đổi sẽ cho kết quả đầu ra như ý muốn
Tóm lại các kỹ thuật lập trình chịu lỗi được thiết kế nhằm mục đích cho phép
hệ thống vẫn hoạt động bình thường kể cả trong trường hợp có lỗi phát sinh sau quá trình phát triển hệ thống Tuy nhiên các kỹ thuật lập trình chịu lỗi chỉ
có tác dụng với giai đoạn mã hoá các yêu cầu phần mềm chứ không thể có tác dụng nếu người thiết kế và xây dựng hệ thống không hiểu yêu cầu bài toán thực tế dẫn đến mã hoá sai so với yêu cầu thực tế
Trang 7phần mềm chịu lỗi là một dãy các hành động được thực hiện nhằm mục đích loại bỏ các trạng thái lỗi phần mềm (errors) trong quá trình hoạt động của phần mềm Có hai dạng phục hồi lỗi đó là phục hồi quay lui (backward recovery) và phục hồi tiến (forward recovery)
1.3.1 - Phục hồi quay lui
Khi có lỗi xuất hiện trong một hệ thống phần mềm, hệ thống lúc này có trạng thái lỗi Việc phục hồi hệ thống, như trên đã nói, là cố gắng đưa hệ thống quay trở về trạng thái không có lỗi (error-free) Kỹ thuật phục hồi quay lui thực hiện điều này bằng cách đưa hệ thống quay trở lại trạng thái trước đó, khi chưa có lỗi xảy ra Kỹ thuật này luôn mặc định rằng trạng thái của hệ thống trước đó không có lỗi Ta gọi đó là điểm phục hồi hệ thống (checkpointing) đã được xác định trước Trạng thái của hệ thống tại điểm phục hồi này không bị ảnh hưởng bởi các lỗi vừa xảy ra Kỹ thuật phục hồi quay lui có một số ưu điểm sau:
Áp dụng tốt đối với các lỗi chưa thể dự đoán có thể xảy ra trong quá trình hoạt động của phần mềm
Nguyên lý hoạt động của kỹ thuật này cho phép áp dụng rộng rãi mà không cần phải sửa đổi nhiều khi ứng dụng cho các phần mềm khác nhau
Kỹ thuật này được áp dụng mà không cần biết nội dung lỗi khi nó xảy ra Yêu cầu duy nhất của kỹ thuật này là biết được trạng thái an toàn trước trạng thái lỗi hiện tại
Được áp dụng một cách trong suốt đối với người sử dụng với bất kỳ lỗi phần mềm nào
Áp dụng kỹ thuật phục hồi quay lui có thể loại bỏ bớt một số lỗi mà
có thể sau khi được phục hồi lỗi sẽ bị mất đi, có nghĩa là nếu chương trình thực hiện mà không xảy ra lỗi như trước
Trang 8Tuy nhiên kỹ thuật phục hồi quay lui cũng có một số nhược điểm nhất định:
Kỹ thuật này tiêu tốn nhiều tài nguyên hệ thống (thời gian, sự tính toán, sự lưu trữ )
Thông thường hệ thống tạm thời dừng lại trong khi thực hiện phục hồi
Nếu trong một hệ thống có nhiều tiến trình, một trong số đó sử dụng
kỹ thuật phục hồi quay lui thì hiệu ứng domino (vấn đề này sẽ được nói đến ở phần sau) có thể xảy ra đối với toàn hệ thống
1.3.2 - Phục hồi tiến
Như đã nói ở trên, khi có lỗi xảy ra trong hệ thống phần mềm, các kỹ thuật phục hồi sẽ tìm cách đưa hệ thống về trạng thái không có lỗi Kỹ thuật phục hồi tiến thực hiện việc này bằng cách bỏ qua bước phát sinh ra lỗi hoặc tìm một con đường khác để hệ thống tiếp tục hoạt động với hy vọng con đường mới không sinh ra lỗi Kỹ thuật này có một số ưu điểm sau:
Kỹ thuật này áp dụng khá hiệu quả cho các hệ thống thời gian thực, tại vì khác với kỹ thuật phục hồi quay lui, nó không làm tốn thời gian chung của hệ thống khi được kích hoạt
Đối với các lỗi được đoán biết trước, sử dụng kỹ thuật này sẽ rất phù hợp
Một số nhược điểm của kỹ thuật phục hồi tiến:
Với nguyên lý hoạt động như trên, kỹ thuật này chỉ được áp dụng cho từng hệ thống cụ thể với các yêu cầu cụ thể
Kỹ thuật này chỉ loại bỏ đi các lỗi đã được nhận biết trước Do đó yêu cầu tiên quyết của hệ thống khi áp dụng kỹ thuatạ này là phải hiểu biết một cách chi tiết các lỗi có thể gây ra cho hệ thống khi hoạt động
Trang 91.4 – Quan niệm “dự phòng” trong việc xây dựng phần mềm chịu lỗi
Ý tưởng chính của việc xây dựng bất kỳ một hệ thống chịu lỗi nào đó là có sẵn một số tài nguyên để làm dự phòng cho hệ thống Có thể là dự phòng về phần cứng, dự phòng về phần mềm, dự phòng về dữ liệu hoặc dự phòng về thời gian
Chẳng hạn để một hệ thống máy tính hoạt động với rủi ro ít xảy ra, người ta thường sử dụng các phần cứng dự phòng trường hợp nếu hệ thống máy tính
đó bị hỏng hóc thì lập tức được thay thế hoặc bổ sung bởi các phần khác tốt hơn Đối với phần mềm, dự phòng bao gồm dự phòng các chương trình, các module, các đối tượng được phần mềm đó sử dụng hoặc cũng có thể sử dụng thời gian để dự phòng cho hệ thống Với trọng tâm nghiên cứu về vấn đề xây dựng phần mềm chịu lỗi thì các tài nguyên dự phòng chính cho một hệ thống phần mềm đó là dự phòng các chương trình và dự phòng dữ liệu
1.4.1 - Dự phòng phần mềm
Phần mềm ở đây bao gồm các chương trình, các module, các hàm hay các đối tượng được sử dụng trong hệ thống Về mặt ý tưởng nó được mượn từ ý tưởng dự phòng phần cứng Tuy nhiên, không như phần cứng là chỉ cần thay thế một phần cứng khác tương đương thì hệ thống sẽ hoạt động tốt trở lại, nếu phần mềm cũng được dự phòng như vậy thì nó chỉ làm cho hệ thống lại sinh
ra lỗi như trước mà thôi Do vậy thông thường những phần mềm dự phòng được xây dựng theo cách khác hẳn so với phần mềm chính thức Các phần mềm dự phòng khác với phần mềm chính thức cả về phương pháp tiếp cận bài toán, về cách thiết kế bài toán, khác về ngôn ngữ lập trình và thậm chí khác cả
về đội ngũ nhân sự phát triển hệ thống đó
1.4.2 - Dự phòng dữ liệu
Có một cách khác để xây dựng phần mềm chịu lỗi thông qua việc dữ liệu đầu vào của hệ thống được biến đổi một cách thích hợp sao cho dữ liệu đầu vào
Trang 10không là nguyên nhân khiến hệ thống bị lỗi Nói cách khác là nếu dữ liệu đầu vào gây lỗi cho hệ thống thì ngay lập tức nó phải thay đối giá trị của dữ liệu đầu vào với hy vọng giá trị mới của dữ liệu đầu vào sẽ không làm cho hệ thống bị lỗi như trước
1.5 – Các phương pháp xây dựng phần mềm chịu lỗi
1.5.1 – Phương pháp đa thiết kế
Kỹ thuật đa thiết kế thực hiện xây dựng nhiều biến thể phần mềm khác nhau nhằm phục vụ một công việc được bài toán đặt ra Cần phải lưu ý rằng các biến thể phần mềm phải được thiết kế và phát triển hoàn toàn khác nhau, chứ không phải chỉ đơn thuần copy thành nhiều biến thể cùng một cách thiết kế và phát triển Tại vì nếu thực hiện như vậy thì không những làm giảm tính tin cậy của phần mềm mà còn có thể làm tăng số lượng lỗi của phần mềm hiện tại Mỗi nhóm phát triển đều có trách nhiệm triển khai và đưa ra kết quả như bài toán đã yêu cầu Trong toàn bộ quá trình hệ thống hoạt động thì ít nhất phải có một biến thể hoạt động kèm theo Mục đích của phương pháp đa thiết
kế là làm sao để các biến thể chương trình làm dự phòng lẫn nhau và hoạt động độc lập với nhau nhất có thể Với mục đích đó người xây dựng hệ thống
hy vọng rằng các lỗi phát sinh ở một biến thể phần mềm này có thể không xảy
ra với biến thể phần mềm khác, do vậy hệ thống vẫn tiếp tục thực hiện một cách bình thường.[4]
Dữ liệu đầu vào được cung cấp cho các biến thể để các biến thể hoạt động Do
có nhiều biến thể cho nên cũng có nhiều kết quả đầu ra, các kết quả đầu ra được tổng hợp lại để đưa qua một bộ quyết định, bộ quyết định sẽ xác định biến thể nào cho kết quả đúng để rồi sau đó chuyển tiếp cho phần xử lý tiếp theo Trong thực tế có rất nhiều thuật toán sử dụng để xây dựng bộ quyết
Trang 11định, tùy thuộc vào đặc điểm cũng như tình huống cụ thể của từng bài toán để chọn lựa giải thuật bộ quyết định cho phù hợp
Phương pháp đa thiết kế có thể áp dụng cho nhiều lớp trong một hệ thống, có thể áp dụng cho phần cứng, phần mềm ứng dụng, phần mềm hệ thống, hệ điều hành Những trường hợp đó người ta gọi là đa thiết kế nhiều mức
Hình vẽ dưới đây minh họa cho kỹ thuật đa thiết kế:
1.5.2 – Phương pháp đa dữ liệu
Ta có khái niệm failure domain, tức là tập các đầu vào gây ra lỗi phần mềm Còn failure region là biểu diễn hình học của khái niệm failure domain, nó mô
tả tính phân tán của các điểm trong failure domain và thông qua đó nó sẽ xác định tính hiệu quả của kỹ thuật đa dữ liệu.[4]
Kỹ thuật đa dữ liệu thực hiện việc biến đổi dữ liệu đầu vào của hệ thống thành nhiều đầu vào khác nhau, thông qua kỹ thuật này người thiết kế mong muốn
từ một đầu vào nằm trong failure region sẽ biến đổi thành một đầu vào khác nằm ngoài failure region Về mặt toán học có thể nói rằng R là một thuật toán biến đổi dữ liệu, nó thực hiện biến đổi đầu vào x thành đầu vào mới y=R(x)
Trang 12Đầu vào y có thể xấp xỉ x hoặc có thể nó chứa thông tin x ở một khuôn dạng khác Và ta có chương trình con P và R sẽ xác định một mối liên kết giữa P(x)
và P(y) như hình vẽ minh hoạ dưới đây:
Trong thực tế, kỹ thuật đa dữ liệu tồn tại với nhiều cấu trúc khác nhau Chẳng hạn như hình vẽ dưới đây mô tả sơ đồ khối của kỹ thuật đa dữ liệu khác, ngoài việc biến đổi dữ liệu đầu vào trước khi thực hiện chương trình con P cấu trúc này còn thực hiện việc điều chỉnh trên kết quả P(y) những sai lệch có thể xuất hiện sau khi biến đổi dữ liệu đầu vào trước đó như được minh hoạ trong hình 1.3
Hoặc có thể xây dựng một cấu trúc khác của kỹ thuật đa dữ liệu (Hình 1.4)
Dữ liệu đầu vào được phân tích thành nhiều mẩu dữ liệu nhỏ, chương trình sẽ được thực hiện với từng mầu dữ liệu nhỏ nay rồi sau đó kết quả sẽ được tổng hợp lại từ nhiều kết quả “nhỏ”
Trang 13Ta thấy rằng, đối với kỹ thuật đa dữ liệu thì điều quan trọng nhất là làm sao
để thiết kế được bộ biến đổi dữ liệu (Data re-expression algorimths) Tuy nhiên trong thực tế, việc thiết kế bộ DRA phụ thuộc rất nhiều vào đặc điểm
dữ liệu đầu ra của các biến thể chương trình
1.5.3 – Phương pháp đa thời điểm
Kỹ thuật đa thời điểm đưa ra ý tưởng loại bỏ lỗi phần mềm bằng cách thực hiện một sự kiện nào đó (trong hệ thống phần mềm) tại nhiều thời điểm khác nhau Kỹ thuật này đặc biệt hiệu quả đối với những lỗi phần mềm xảy ra trong khoảng thời gian “ngắn” Các phần mềm sử dụng kỹ thuật thiết kế này được
sử dụng dữ liệu tại các thời điểm khác nhau, do vậy trong một số trường hợp thì kỹ thuật này cho kết quả tương tự kỹ thuật đa dữ liệu
Hình 1.5 minh hoạ cho kỹ thuật đa thời điểm Các đầu vào được hệ thống nhận được lúc t t i, i1,t i2 Đầu vào tại thời điểm t i cho ra kết quả của nó, giả sử rằng kết quả này là sai, phầm mềm sẽ tiếp tục thực hiện với đầu vào tại thời điểm t i1, giả sử nó cho ra kết quả đúng thì phần mềm sẽ chấp nhập đầu vào tại thời điểm này Nếu hệ thống được thiết lập để nhận ba đầu vào thì đến lúc này đầu vào tại thời điểm t sẽ được loại bỏ
Trang 141.6 - Kết luận
Nhu cầu nâng cao độ tin cậy của các hệ thống phần mềm ngày càng cấp bách đặc biệt là trong một số lĩnh vực khoa học ứng dụng công nghệ cao Tuy nhiên thực tế trong quá trình hoạt động phần mềm rất thường xảy ra lỗi Để nâng cao độ tin cậy của phần mềm người ta thường sử dụng các biện pháp sau:
Biện pháp tránh lỗi (fault avoidance)
Biện pháp loại bỏ lỗi (fault removal)
Biện pháp dự đoán lỗi (fault forecasting)
Biện pháp xây dựng phần mềm chịu lỗi (fault tolerance)
Các kỹ thuật xây dựng phần mềm chịu lỗi thường sử dụng các phương pháp phục hồi trạng thái hệ thống như phương pháp phục hồi quay lui và phương pháp phục hồi tiến Mỗi phương pháp đều có ưu điểm, nhược điểm riêng Phụ thuộc vào từng bài toán cụ thể người thiết kế có thể sử dụng phương pháp nào mang lại hiệu quả cao nhất
Ngoài ra các kỹ thuật xây dựng phần mềm chịu lỗi được thiết kế dựa trên một
số quan niệm về tính “dự phòng” trong hệ thống Có nghĩa là người xây dựng
Trang 15hệ thống sẽ xây dựng một số thành phần để “dự phòng” nhằm sử dụng đến khi cần thiết Dựa trên những quan niệm nền tảng đó người ta đưa ra một số phương pháp xây dựng phần mềm chịu lỗi:
Phương pháp đa thiết kế: Dựa trên ý tưởng xây dựng nhiều biến thể phần mềm dự phòng cùng giải quyết chung một bài toán đặt ra
Phương pháp đa dữ liệu: Thực hiện giải quyết bài toán với nhiều dữ liệu đầu vào khác nhau bằng cách biến đổi dữ liệu đầu vào sao cho vẫn giữ được ý nghĩa cũng như không làm sai lệch đi kết quả tính toán
Phương pháp đa thời điểm: Thường được áp dụng trong các hệ thống mà yếu tố thời gian đóng vai trò quan trọng
Mỗi phương pháp đều có ưu nhược điểm riêng và đều có thể được áp dụng tuỳ thuộc vào yêu cầu cụ thể của từng bài toán
Chương tiếp theo sẽ trình bày chi tiết sự hoạt động của các kỹ thuật thuộc hai nhóm phương pháp đa thiết kế và phương pháp đa dữ liệu Ngoài ra cũng xây dựng một số phương pháp trong quá trình xác định kết quả cuối cùng của hệ thống
Trang 16Chương 2 – CÁC KỸ THUẬT XÂY DỰNG PHẦN MỀM CHỊU LỖI
2.1 – Các kỹ thuật đa thiết kế
Nguyên tắc cơ bản của kỹ thuật đa thiết kế là xây dựng nhiều thành phần phần mềm (software components) để giải quyết cùng một bài toán Với giả định các lỗi của các thành phần phền mềm cấu thành hệ thống hiếm khi trùng lặp nhau và nếu giải sử có trường hợp này xảy ra thì kết quả của các thành phần cũng khác nhau đủ để phân biệt được kết quả nào đúng hoặc đúng nhất Với việc sử dụng kỹ thuật này, người thiết kế phần mềm hy vọng rằng xác suất phần mềm bị lỗi sẽ giảm xuống [7,4]
Trong thực tế có nhiều kỹ thuật áp dụng nguyên tắc này, chẳng hạn như kỹ thuật Recovery blocks (RcB), kỹ thuật N-version programming (NVP), kỹ thuật Distributed recovery blocks (DRB), kỹ thuật N self-checking programming (NSCP), kỹ thuật Consensus recovery blocks (CRB), kỹ thuật Acceptance voting (AV) Mỗi kỹ thuật trên đều có những điểm mạnh, điểm yếu riêng Tùy theo từng bài toán cụ thể mà nên ứng dụng kỹ thuật phù hợp
2.1.1 - Kỹ thuật Recovery Blocks (RcB)
Kỹ thuật RcB là một trong những kỹ thuật xây dựng phần mềm chịu lỗi cơ bản nhất Bên cạnh tính chất “đa thiết kế”, RcB còn có thể được xem như là
kỹ thuật xây dựng phần mềm chịu lỗi động, có nghĩa là việc chọn lựa kết quả của các biến thể được điều chỉnh phụ thuộc vào bộ kiểm tra chấp nhận kết quả (acceptance test - AT) Thực tế cho thấy rằng bất kỳ một hệ thống nào cũng
có thể được thiết kế và phát triển theo nhiều cách khác nhau Với mỗi cách thiết kế và phát triển khác nhau hệ thống sẽ có độ tin cậy hệ thống, mức độ tối
ưu trong quản lý bộ nhớ, thời gian thực thi hệ thống và nhiều chỉ tiêu khác nữa khác nhau Kỹ thuật RcB sẽ ưu tiên thực hiện các giải pháp có mức độ tối
Trang 17ưu hoá hệ thống là lớn nhất trước sau đó lần lượt đến các giải pháp còn lại để nhằm đạt được kết quả cuối cùng
Mô hình kỹ thuật RcB bao gồm các khối chính sau:[4]
Khối xác định chấp nhận kết quả hay không (Acceptance Test - AT): Mục đích chính của AT là xác định kết quả đầu ra của các biến thể chương trình Chức năng của AT không nhất thiết phải kiểm tra tính đúng đắn của kết quả đầu ra mà có thể chỉ cần kiểm tra tính hợp
lý của nó là đủ
Khối chương trình chính chính (Primary Alternate): Đây là hành động được thực hiện đầu tiên của một chu trình kỹ thuật RcB Kết quả của bước này cũng được kiểm tra bằng AT, nếu được chấp nhận thì thuật toán kết thúc và thoát khỏi chu trình RcB Nếu kết quả không được chấp nhận thì thuật toán sẽ quay lui (backward error recovery) và các chương trình thay thế (alternate modules) sẽ lần lượt được thực hiện dưới sự kiểm tra của AT Quy trình cứ tiếp tục cho đến khi có một module vượt qua được sự kiểm tra của AT
Các khối chương trình thay thế (Alternate modules): Các module của khối này được thiết kế hoàn toàn khác nhau, độc lập nhau mặc
dù chúng giải quyết cùng một yêu cầu bài toán đặt ra Để đảm bảo tính “Đa thiết kế”, thậm chí mỗi module có thể được thiết kế và thực hiện theo các cách tiếp cận khác nhau
Cú pháp của sự hoạt động của các khối được mô tả tổng quát như dưới đây:
Trang 18else byAlternate n
else failure exception
Như đã được mô tả, việc đầu tiên mà RcB thực hiện là bảo đảm thoả mãn các điều kiện của AT bằng cách sử dụng chương trình chính, nếu kết quả không được thoả mãn bởi AT thì (n-1) các cách thực hiện bài toán khác tiếp theo sẽ được sử dụng lần lượt cho đến khi nào kết quả của thuật toán thoả mãn AT Trong trường hợp không có một kết quả của chương trình thay thế nào thỏa mãn thì lỗi sẽ xảy ra
Sơ đồ khối của kỹ thuật RcB như sau:
2.1.2 - Kỹ thuật N-Version Programming (NVP)
Cũng giống như kỹ thuật RcB, kỹ thuật NVP cũng là một trong những kỹ thuật xây dựng phần mềm chịu lỗi đa thiết kế Tuy được gọi là kỹ thuật “đa
Trang 19thiết kế” giống như RcB nhưng NVP là kỹ thuật tĩnh (khác với RcB là kỹ thuật động), có nghĩa là bài toán sử dụng kỹ thuật NVP được thực thi trên nhiều tiến trình hoặc biến thể chương trình khác nhau và kết quả cuối cùng chỉ được chấp nhận nếu nó đã được chấp nhận bởi bộ quyết định Kỹ thuật NVP sử dụng ít nhất hai (hay nhiều) biến thể chương trình (variants) khác nhau để cùng giải quyết một bài toán được đặt ra thông qua một bộ phận gọi
là bộ phận quyết định (Decision Mechannism - DM) để quyết định lựa chọn kết quả tốt nhất cho bài toán từ nhiều kết quả khác nhau của các biến thể chương trình khác nhau Do vậy dễ dàng thấy rằng điểm mấu chốt của kỹ thuật NVP là các biến thể khác nhau của phần mềm và bộ phận quyết định
Để giảm thiểu khả năng trùng lặp sai sót giữa các biến thể chương trình, mỗi biến thể chương trình thông thường được thiết kế và phát triển bởi các nhóm phát triển khác nhau, bằng các ngôn ngữ lập trình khác nhau [4]
Sự hoạt động kỹ thuật NVP được mô tả như sau:
run Version 1, Version 2,…, Version n
if (Decision Mechanism (Result 1, Result 2,…, Result n ))
return Result else failure exception
Các biến thể trong kỹ thuật NVP được thực thi song song trên nhiều hệ thống phần cứng khác nhau Kết quả của từng biến thể chương trình được xác định tính “đúng”, “sai” thông qua bộ phận quyết định Nếu một trong các biến thể cho kết quả “đúng” thì thuật toán sẽ có lời giải, ngược lại thì lỗi sẽ xảy ra Trong trường hợp có nhiều biến thể cùng cho kết quả “đúng” thì bộ phận quyết định có nhiệm vụ tìm ra kết quả nào là kết quả “đúng nhất” Trong thực
tế có rất nhiều phương pháp để thiết kế bộ quyết định, tùy từng trường hợp cụ thể với từng bài toán cụ thể để có thể chọn lựa được phương pháp xây dựng
bộ quyết định thích hợp nhất Ở phần sau của luận văn sẽ trình bày một số
Trang 20giải thuật xây dựng bộ quyết định (và bộ kiểm tra chấp nhận kết quả) thường được sử dụng trong các kỹ thuật xây dựng phần mềm chịu lỗi
Sơ đồ cấu trúc hoạt động của kỹ thuật NVP như sau:
Nếu muốn tăng hiệu quả hoạt động của kỹ thuật NVP thì phải làm sao để cực đại hoá sự độc lập trong việc hoạt động của các biến thể chương trình và đồng thời cực tiểu hoá xác suất làm cho hai (hay nhiều) biến thể chương trình cùng xuất hiện một lỗi tương tự nhau
2.1.3 - Kỹ thuật N Self-Checking Programming (NSCP)
Kỹ thuật NSCP được xây dựng trên cơ sở phát triển của kỹ thuật NVP Kiến trúc của NSCP được chia thành các khối trong đó mỗi khối bao gồm các biến thể chương trình Nói cách khác các biến thể chương trình trong các khối khác nhau sẽ được thực hiện song song, kết quả của từng các biến thể sẽ được đưa
Trang 21qua bộ kiểm tra kết quả, nếu được chấp nhận kết quả đó sẽ được lưu trữ lại (được xem như kết quả của khối đó) để tiếp tục so sánh nó với kết quả của các biến thể khác (của khối khác) để cuối cùng xác định một kết quả duy nhất của toàn bộ hệ thống
Kiến trúc của kỹ thuật NSCP được minh họa qua hình 2.3 (với bốn biến thể chương trình):
Dữ liệu đầu vào được cung cấp cho các biến thế chương trình Sau khi có kết quả đầu ra của các biến thể lần lượt từng đôi một được kiểm tra để xác định tính đúng đắn của kết quả, cứ như vậy cuối cùng sẽ xác định được đầu ra của toàn bộ hệ thống
Trong trường hợp trên, hệ thống sẽ báo lỗi khi kết quả của cả hai cặp biến thể chương trình cùng không được chấp nhận hoặc được chấp nhận bước 1 nhưng không được chấp nhận ở bước 2 Hình 2.4 sẽ minh họa rõ hơn các trường hợp kết quả của hệ thống áp dụng kỹ thuật NSCP
Trang 22Giải thuật của NSCP được mô tả như sau:
run Variants 1 and 2,
Variants 3 and 4 compare Results1 and 2compare Results 3 and 4
if not match
set NoMatch1
else set Result Pair 1
if not match set NoMatch2 else set Result Pair 2
if NoMatch1 and not NoMatch2, Result = Result Pair 2
else if NoMatch2 and not NoMatch1, Result = Result Pair 1
else if NoMatch1 and NoMatch2, raise exception
else if not NoMatch1 and not NoMatch2
Trang 23then compare Result Pair 1 and 2
if not match, raise exception
if match, Result = Result Pair 1 or 2
return Result
Dễ dàng thấy rằng để tăng hiệu quả hoạt động của NSCP, các biến thể chương trình nên được thực hiện song song
2.1.4 - Kỹ thuật Consensus Recovery Block (CRB)
Kỹ thuật CRB được xây dựng dựa trên ý tưởng phối kết hợp hai kỹ thuật RcB
và NVP lại với nhau Ý định của những người muốn sử dụng kỹ thuật CRB là
để giảm bớt tính quan trọng của bộ kiểm tra chấp nhận kết quả (AT) được sử dụng trong RcB và mặt khác CRB cũng có thể giải quyết được trường hợp có nhiều kết quả đầu ra đúng mà kỹ thuật NCP chưa giải quyết triệt để được
Kỹ thuật CRB bao gồm nhiều biến thể chương trình khác nhau, mỗi biến thể chương trình được gán ở một mức khác nhau (có thể tuỳ theo tính tin cậy của biến thể chương trình) Cũng tương tự như NVP, các biến thể chương trình được thực hiện song song và kết quả đầu ra của các biến thể được gửi đến bộ quyết định xem xét để có những kết luận thích hợp Nếu bộ quyết định vẫn không xác định được kết quả đúng thì kết quả của biến thể chương trình được xếp ở mức ưu tiên cao nhất sẽ được gửi đến bộ kiểm tra chấp nhận kết quả (AT), nếu vẫn chưa xác định được kết quả cuối cùng thì kết quả của biến thể
có mức ưu tiên tiếp theo sẽ được gửi đến bộ kiểm tra chấp nhận kết quả (AT)
và cứ như vậy cho đến khi có một kết quả được chấp nhận hoặc không còn kết quả của biến thể chương trình nào nữa (lúc đó hệ thống sẽ báo lỗi)
Giải thuật của kỹ thuật CRB được viết như sau:
run Ranked Variant 1, Ranked Variant 2, , Ranked Variant n
if (Decision Mechanism(Result 1, Result 2, ,Result n))
return Result
Trang 24ensure Acceptance Test
by Ranked Variant 1 (Result)
else by Ranked Variant 2 (Result)
else byRanked Variant n (Result)
else raise failure exception
return Result
Rõ ràng giải thuật của CRB được chia thành hai phần, phần NVP và phần RcB Trong phần NVP, các kết quả đầu ra của các biến thể được thực hiện song song được cung cấp cho bộ quyết định để xác định kết quả, nếu xác định được thì hệ thống dừng thực hiện và kết quả trả về là kết quả do bộ quyết định lựa chọn Ngược lại, các kết quả đầu ra được lần lượt kiểm tra bởi bộ kiểm tra, nếu vẫn không có kết quả nào được chấp nhận thì hệ thống sẽ thông báo lỗi
Hình 2.5 minh họa kiến trúc hoạt động của kỹ thuật CRB:
Trang 252.1.5 - Kỹ thuật Acceptance Voting (AV)
Kỹ thuật AV sử dụng cả hai gồm bộ kiểm tra chấp nhận kết quả và bộ quyết định tham gia xác định kết quả cuối cùng AV được xây dựng dựa trên phương pháp phục hồi tiến để tăng tính chịu lỗi của phần mềm Trong AV tất
cả các biến thể chương trình thực hiện song song, rồi sau đó các kết quả được đánh giá bằng các (hoặc một) bộ kiểm tra chấp nhận kết quả và chỉ các kết quả được chấp nhận mới được gửi đến bộ quyết định, bộ quyết định sẽ có nhiệm vụ chọn lựa trong các kết quả đầu vào kết quả đúng nhất cuối cùng Đối với kỹ thuật AV, hệ thống sẽ báo lỗi khi hoặc không có kết quả nào vượt qua được bộ kiểm tra chấp nhận kết quả hoặc bộ quyết định không chọn được kết quả nào đúng Giải thuật của kỹ thuật AV được mô tả như sau:
run Variant 1, Variant 2, , Variant n
ensure Acceptance Test 1 by Variant 1 ensure Acceptance Test 2 by Variant 2
ensure Acceptance Test n by Variant n [Result i, Result j, , Result m pass the AT]
if (Decision Mechanism (Result i, Result j, , Result m))
return Result else
return failure exception
Như giải thuật đã trình bày trên, n biến thể chương trình được thực hiện song song như trong kỹ thuật NVP Sau đó mỗi kết quả của mỗi biến thể chương trình được cung cấp cho các bộ kiểm tra chấp nhận kết quả (AT) Trong thực
tế có thể sử dụng mỗi bộ AT để kiểm tra kết quả của một biến thể hoặc có thể
sử dụng một bộ AT để kiểm tra tất cả các kết quả của các biến thể Tiếp đến tất cả các kết quả đã được bộ AT chấp nhận sẽ được tiếp tục đưa đến bộ quyết định để xác định kết quả cuối cùng Trong trường hợp không có kết quả của
Trang 26biến thể chương trình nào được bộ AT chấp nhận thì hệ thống sẽ báo lỗi Trường hợp chỉ có một kết quả được chấp nhận thì bộ kiểm tra coi như đó là kết quả cuối cùng của hệ thống
Kiến trúc của kỹ thuật AV tương tự như kỹ thuật NVP Thông thường nó cũng được triển khai trên hệ thống gồm nhiều bộ phần cứng hoạt động song song Sự khác nhau chủ yếu của NVP và AV là kỹ thuật AV có thêm bộ kiểm tra chấp nhận kết quả
Hình vẽ sau mô tả quả trình hoạt động của AV:
2.2 – Các kỹ thuật đa dữ liệu
Khác với các kỹ thuật đa thiết kế, nguyên tắc chung của kỹ thuật đa dữ liệu là
sử dụng nhiều bộ dữ liệu đầu vào để phát hiện cũng như để “chịu lỗi” những lỗi phát sinh trong quá trình hệ thống hoạt động
Trang 272.2.1 - Kỹ thuật Retry Block (RtB)
Ý tưởng chính của kỹ thuật RtB là thực hiện cung cấp các bộ dữ liệu đầu vào khác nhau cho cùng một thuật toán xử lý với hy vọng một trong số bộ dữ liệu đầu vào đó sẽ cho kết quả đúng Những bộ đầu vào khác nhau được xác định dựa trên bộ đầu vào ban đầu và được biến đổi (Re-expressed) theo một số nguyên tắc nào đó RtB có thể sử dụng một bộ đếm thời gian (Timer) để xác định thời hạn thực hiện của thuật toán, nếu thời gian còn cho phép thì thuật toán chính vẫn được tiếp tục hoạt động, ngược lại nếu thời gian đã hết thì lập tức RtB thực hiện thuật toán dự phòng
Cũng tương tự như kỹ thuật RcB, kỹ thuật RtB sử dụng bộ kiểm tra chấp nhận của kết quả (AT) để xác định kết quả cuối cùng Nếu một trong những kết quả trong quá trình thực hiện thuật toán được AT chấp nhật thì RtB kết thúc, còn nếu kết quả đó không được AT chấp nhận thì RtB thực hiện biến đổi dữ liệu đầu vào rồi tiếp tục thực hiện thuật toán Việc này được thực hiện lặp đi lặp lại cho đến khi bộ kiểm tra chấp nhận kết quả hoặc hết thời hạn thực hiện thuật toán Trong trường hợp thời hạn thực hiện thuật toán kết thúc thì RtB sẽ gọi thuật toán dự phòng với dữ liệu đầu vào ban đầu để thực hiện tiếp tục bài toán
Sự hoạt động của kỹ thuật RtB dược mô tả như sau:
ensureAcceptance Test
byPrimary Algorithm(Original Input)
else byPrimary Algorithm(Re-expressed Input)
else byPrimary Algorithm(Re-expressed Input)
…
…[Dealline Expires]
else byBackup Algorithm(Original Input)
else failure exception
Trang 28Hình vẽ sau sẽ giúp nhìn thấy rõ hơn cấu trúc và sự hoạt động của RtB:
Với cấu trúc như trên, đầu tiên RtB thực hiện chương trình chính với bộ đầu vào cho trước, rồi sử dụng bộ kiểm tra để kiểm tra kết quả đầu ra Nếu bộ tính chấp nhận của kết quả không chấp nhận thì bộ dữ liệu đầu vào sẽ được biến đổi, sau đó bộ dữ liệu này sẽ được chương trình chính xử lý lại, mọi việc cứ tiếp tục như vậy cho đến khi kết quả của chương trình được bộ chấp nhận kết quả chấp nhận hoặc thời hạn thi hành chương trình đã hết Nếu hết thời hạn thì một chương trình dự phòng với số liệu đầu vào ban đầu sẽ được kích hoạt
để có được dữ liệu đầu ra, bộ kiểm tra tính chấp nhận của kết quả sẽ kiểm tra lần cuối cùng dữ liệu đầu ra này, nếu kết quả đúng thì chấp nhận kết quả, ngược lại thì lỗi sẽ xảy ra
Trang 29Kỹ thuật RtB có thể được cải tiến để mang lại hiệu quả hơn, sau đây là một số điểm có thể được thay đổi nhằm nâng cao khả năng hoạt động của RtB:
Trong một số trường hợp cần thiết phải xác định số lần dữ liệu đầu vào được phép biến đổi và đó cũng chính là số lần chương trình chính được thực hiện với các dữ liệu đầu vào khác nhau Việc xác định này có thể sử dụng để làm tăng khả năng dừng của thuật toán
mà không cần phải sử dụng bộ đếm thời gian
Bộ kiểm tra tính chấp nhận của kết quả (AT) được sử dụng trong kỹ thuật RtB cũng có thể được tổng hợp từ nhiều bộ kiểm tra con khác nhau Thêm nữa có thể sử dụng các bộ kiểm tra khác nhau để kiểm tra thuật toán chính và thuật toán dự phòng, chứ không nhất thiết chỉ dùng một bộ kiểm tra duy nhất để kiểm tra cả hai thuật toán Tại vì trong thực tế, có thể ý nghĩa toán học hay chức năng của thuật toán
dự phòng hoàn toàn khác với thuật toán chính Tuy nhiên, nếu thuật toán dự phòng và thuật toán chính đều được xây dựng dựa trên cùng một ý nghĩa toán học thì nên sử dụng một bộ kiểm tra để kiểm tra cả hai thuật toán
Có hai cách để thực hiện việc biến đổi dữ liệu đầu vào Cách thứ nhất là có thể sử dụng chỉ một bộ biến đổi nhưng thực hiện biến đổi theo nhiều cách khác nhau Cách thứ hai là sử dụng nhiều bộ biến đổi khác nhau để biến đổi dữ liệu đầu vào
2.2.2 - Kỹ thuật N-Copy Programming (NCP)
Thực tế NCP chỉ là một kỹ thuật mở rộng của RtB, trong đó có nhiều bộ biến đổi dữ liệu đầu vào cùng được thực hiện song song cùng một lúc nhằm cung cấp đầu vào cho nhiều bản sao từ một chương trình duy nhất, tất nhiên các bản sao chương trình này cũng được thực hiện song song NCP sử dụng bộ quyết định để xác định kết quả cuối cùng Tùy thuộc vào từng hệ thống cụ thể
Trang 30có thể sử dụng một hoặc nhiều bộ biến đổi dữ liệu (DRA) để thực hiện biến đổi dữ liệu đầu vào của các biến thể chương trình Giải thuật hoạt động của NCP như sau:
run DRA 1, DRA 2, , DRA n
run Copy 1(result of DRA 1),
Copy 2(result of DRA 2), , Copy n(result of DRA n)
if Decision Mechanism (Result 1, Result 2, , Result n)
return Result else failure exception
Sơ đồ khối cấu trúc và sự hoạt động của NCP được mô tả như sau:
Trang 31Như đã được mô tả qua sơ đồ trên, trước hết NCP thi hành các bộ biến đổi dữ liệu song song rồi sau đó từ các dữ liệu đầu vào đã có thực hiện cùng lúc các bản sao chương trình tương ứng với các dữ liệu đầu vào Kết quả của từng bản sao chương trình được tổng hợp lại và được xử lý thông qua một bộ quyết định để chọn được kết quả đúng Trong trường hợp bộ quyết định không tìm được kết quả đúng thì NCP sẽ báo lỗi
Tương tự như các kỹ thuật khác, NCP có thể sử dụng nhiều bộ quyết định khác nhau ứng với từng bản sao chương trình để lựa chọn được kết quả cuối cùng Thêm nữa bộ quyết định lựa chọn kết quả không nhất thiết phải chờ kết quả của tất cả các bản sao mà chỉ cần đưa ra quyết định khi có một số kết quả nhất định nào đó Nếu kết quả đã được tìm thấy thì lập tức dừng toàn bộ sự hoạt động của các bản sao còn lại để tiết kiệm thời gian của như tài nguyên của hệ thống
2.2.3 - Kỹ thuật Two-Pass Adjudicators (TPA)
Kỹ thuật TPA được xây dựng dựa trên sự kết hợp của cả kỹ thuật đa dữ liệu lẫn kỹ thuật đa thiết kế Cụ thể hơn, TPA sử dụng một hoặc nhiều bộ biến đổi
dữ liệu và ít nhất là hai biến thể chương trình để giải quyết bài toán đặt ra Hệ thống được xây dựng dựa trên TPA được hoạt động tương tự như NVP, tuy nhiên nếu bộ quyết định không xác định được kết quả cuối cùng thì các kết quả của các biến thể chương trình sẽ được đưa qua những bộ biến đổi dữ liệu tương ứng Các biến thể chương trình lại tiếp tục thực hiện với bộ dữ liệu đầu vào đã được biến đổi trên Bộ quyết định sẽ tiếp tục thực hiện xác định kết quả cuối cùng (nếu nó tồn tại), nếu không quy trình trên lại được lặp lại hoặc dừng tùy thuộc mục tiêu của hệ thống
Trước hết n biến thể chương trình được thực hiện với tham số là bộ dữ liệu đầu vào ban đầu Kết quả của n biến thể chương trình này được gửi đến bộ quyết định Nếu bộ quyết định tìm thấy kết quả đúng thì giải thuật trả lại kết
Trang 32quả đúng đó và dừng lại Ngược lại dữ liệu đầu vào sẽ được biến đổi và các biến thể chương trình tiếp tục được thực hiện với dữ liệu đã được biến đổi đó, kết quả lại được đưa đến bộ quyết định để xác định kết quả cuối cùng Cứ tiếp tục như vậy cho đến khi xác định được kết quả cuối cùng hoặc hệ thống sẽ thông báo lỗi
Giải thuật của TPA được mô tả như sau:
Pass 1:run Variant 1 (original input),
Trang 33Variant 2 (original input),
Variant n (original input)
if (Decision Mechnism
(Result (Pass 1, Variant 1), (Pass 1, Variant 2), ,(Pass 1, Variant n)))
return Result else
Pass 2:run DRA 1, DRA 2, , DRA n
run Variant 1 (result of DRA 1),
Variant 2 (result of DRA 2),
Variant n (result of DRA n)
if (Decision Mechnism
(Result (Pass 2, Variant 1), (Pass 2, Variant 2), ,(Pass 2, Variant n)))
return Result else failure exception
2.3 – Các phương pháp đánh giá kết quả
Như đã nói ở trên, việc đánh giá kết quả có mặt trong khắp các kỹ thuật xây dựng phần mềm chịu lỗi Thực chất của việc đánh giá kết quả là thực hiện các giải thuật ra quyết định với tham số đầu vào là kết quả của các biến thể chương trình để chọn lựa kết quả thích hợp cho hệ thống Tất nhiên, để thực hiện giải thuật đánh giá kết quả trước hết phải xây dựng được các tiêu chí để
có thể xác định được thế nào là một kết quả “đúng”, thế nào là kết quả “đúng nhất” trong một tập gồm nhiều kết quả Trong nhiều trường hợp, tùy mục đích cuối cùng, có thể sử dụng nhiều bộ đánh giá kết quả khác nhau
Nhìn chung đánh giá kết quả được thực hiện thông qua hai phương pháp chính, thứ nhất là đánh giá thông qua các giải thuật quyết định (Decision
Trang 34(Acceptance Test) Cả hai phương pháp đều được áp dụng rộng rãi trong cả
kỹ thuật đa thiết kế và kỹ thuật đa dữ liệu Phương pháp quyết định thực hiện
so sánh, chọn lựa chọn hai hay nhiều kết quả của các biến thể chương trình khác nhau nhằm xác định được kết quả đúng Còn phương pháp kiểm tra sẽ tiến hành kiểm tra các kết quả để xác định kết quả đúng
2.3.1 – Phương pháp quyết định (Decision Mechanism)
Như đã nói, phương pháp quyết định thực hiện so sánh kết quả của hai hay nhiều biến thể chương trình Thông thường trong trường hợp chỉ có hai kết quả được so sánh với nhau thì người ta gọi bộ quyết định lúc ấy là bộ so sánh
“comparator” Bộ quyết định sẽ lựa chọn được kết quả đúng nếu thực sự nó
có tồn tại Có rất nhiều cách để thiết kế giải thuật cho bộ quyết định Tuy nhiên cần phải thấy rằng, bộ quyết định thường được sử dụng tại những điểm
“xung yếu” của các kỹ thuật xây dựng phần mềm chịu lỗi, do đó bộ quyết định phải được thiết kế và phát triển sao cho có tính tin cậy cao và hoạt động
có hiệu quả
Để xây dựng một bộ quyết định hiệu quả cần phải cố gắng xây dựng bộ quyết định sao cho đơn giản nhất có thể Bộ quyết định càng phức tạp thì xác suất gây lỗi càng cao Về mặt nguyên tắc tất cả các bộ quyết định đều có cơ chế hoạt động tương tự nhau và tuân theo các bước sau:
Bước 1: Khởi tạo các biến cần thiết
Bước 2: Nhận dữ liệu đầu vào (là kết quả đầu ra của các biến thể chương trình trong hệ thống)
Bước 3: Sử dụng những thuật toán nhằm chọn lựa được kết quả đúng nhất
Bước 4: Xác định kết quả đúng của hệ thống (hoặc báo lỗi nếu không tìm được kết quả đúng)
Bước 5: Trả lại kết quả cho hệ thống
Trang 35Hiệu quả của bộ quyết định phụ thuộc nhiều vào mức độ và tần số phép thực hiện so sánh của bộ quyết định Nếu thực hiện phép so sánh với tần số thấp hoặc mức độ thấp, ta gọi những bộ quyết định đó là “bộ quyết định thô” Ngược lại là những “bộ quyết định tinh” Nếu sử dụng bộ quyết định thô thì
sẽ giảm được chi phí xây dựng hệ thống, tuy nhiên nó sẽ không đảm bảo tính chính xác của hệ thống Ngược lại, nếu sử dụng bộ quyết định tinh thì sẽ làm tăng chi phí xây dựng hệ thống nhưng sẽ đảm bảo độ chính xác của hệ thống cao hơn
Phần sau đây sẽ tìm hiểu một số phương pháp xây dựng bộ quyết định
2.3.1.1 - Bộ quyết đinh Exact Majority
Bộ quyết định Exact Majority sẽ chọn lựa giá trị đúng là giá trị xuất hiện trong tập các kết quả một cách thường xuyên nhất Gọi n là số lượng các kết quả (tương đương với số lượng biến thể chương trình), m là số lần xuất hiện cần thiết trong tập các kết quả của một kết quả để nó được xem là đúng Theo một số nghiên cứu, số lượng các biến thể chương trình n hiếm khi nhiều hơn
3 Công thức tính của m là m n 1 / 2 .[15]
Ví dụ ta có các kết quả của các biến thể chương trình như sau:
1 12; 2 11; 3 12
r r r Do vậy ta có vecto đầu vào của bộ quyết định là
12,11,12 Trong trường hợp này n=3 Do vậy m n 1 / 2 2 Do vậy kết quả đúng của hệ thống phải xuất hiện ít nhất 2 lần trong vecto đầu vào, cụ thể kết quả đúng lúc này là giá trị 12
Tuy nhiên xây dựng bộ quyết định theo phương pháp này gặp phải một số điểm bất lợi sau:
Phương pháp này mặc định rằng với mỗi biến thể chương trình chỉ cho một kết quả Trong trường hợp biến thể chương trình có nhiều kết quả đầu ra thì bộ quyết định sẽ chọn lựa kết quả thiếu chính xác
Trang 36 Với phương pháp này, nếu kết quả của biến thể chương trình là sai thì nó cũng góp phần làm giảm tính chính xác của bộ quyết định Một số nghiên cứu cho thấy bộ quyết định Exact Majority sẽ có xác suất chọn được kết quả đúng cao khi xác suất các biến thể gây lỗi ít hơn 50% và số lượng biến thể là “lớn”
2.3.1.2 - Bộ quyết định Median
Bộ quyết định Median thực hiện chọn lựa kết quả là giá trị giữa trong tất cả giá trị đầu vào Với phương pháp này, bộ quyết định Median có thể được sử dụng trong các trường hợp đầu vào là số nguyên, số thực hoặc tất cả các giá trị số khác Nó mặc định rằng sẽ không có giá trị kết quả sai nằm trong khoảng hai kết quả đúng và phần lớn các kết quả đầu ra là đúng làm cơ sở để chọn lựa kết quả đúng “nhất” cuối cùng
Như đã nói ở trên, giải thuật quyết định Median chọn lựa kết quả cuối cùng là giá trị ở giữa trong danh sách kết quả R Gọi n là số biến thể chương trình Giá trị ở giữa là giá trị có vị trí nằm ở giữa danh sách R Nếu n là chẵn thì vị trí là n/2 hoặc (n/2 + 1) nếu n lẻ Ví dụ nếu có ba phần tử trong danh sách thì phần tử thứ hai là phần tử được chọn, còn với danh sách có bốn phần tử thì phần tử được chọn sẽ là phần tử có vị trí thứ ba (n/2 + 1 = 4/2 + 1 = 3)
Giả sử ta có hệ thống phần mềm chịu lỗi với ba biến thể chương trình, n=3 Kết quả của từng biến thể lần lượt như sau:
1 2 3
17.5 16.0 18.1
r r r
Trang 37Sơ đồ khối hoạt động của giải thuật quyết định Median được mô tả như hình 2.10 dưới đây:
Phương pháp quyết định Median có những ưu điểm sau:
Giải thuật đơn giản
Trường hợp nhiều kết quả (từ các biến thể chương trình) đều đúng thì Median vẫn chọn được duy nhất một kết quả đúng cuối cùng
Rất phù hợp với các kỹ thuật xây dựng phần mềm chịu lỗi có sử dụng các phép biến đổi dữ liệu
Tuy nhiên phương pháp Median cũng có nhược điểm là trong trường hợp có một kết quả của biến thể chương trình nào đó bị lỗi thì kéo theo bộ quyết định cũng bị lỗi
Trang 382.3.1.3 - Bộ quyết định Mean (Bộ quyết định trung bình)
Bộ quyết định trung bình chọn giá trị trung bình (hoặc trọng số) của tất cả các phần tử kết quả để xác định kết quả cuối cùng Sơ đồ khối hoạt động của phương pháp quyết định trung bình được mô tả như sau:
Ví dụ ta có một hệ thống phần mềm chịu lỗi với ba biến thể chương trình, n=3 Trong đó các kết quả lần lượt như sau:
1 2 3
17.5 16.0 18.1
r r r
Trang 39thể nào vì lý do nào đó không cho kết quả thì bộ quyết định Mean cũng mất tác dụng
Theo một số nghiên cứu chỉ ra rằng bộ quyết định trung bình có xác suất chọn lựa kết quả đúng cao nếu xác suất kết quả lỗi của các biến thể ít hơn 50% 2.3.1.4 - Bộ quyết định Consensus
Phương pháp Consensus là trường hợp tổng quát hóa của phương pháp Majority Phương pháp này chọn lựa kết quả cuối cùng dựa trên mức độ trùng nhau của các phần tử (không quan tâm nhất thiết tần số xuất hiện của phần tử đó) Giả sử n là số lượng các biến thể chương trình, nếu trong danh sách kết quả xuất hiện nhiều kết quả có giá trị giống nhau thì sử dụng phương pháp Majority để chọn kết quả cuối cùng Nếu không thì xét đến trường hợp có bộ giá trị kết quả giống nhau (số lượng phần tử trong mỗi bộ ít hơn trong trường hợp Majority) thì giá trị của phần tử trong bộ đó chính là kết quả được chọn lựa Nếu không thuộc vào hai trường hợp trên, xét đến trường hợp có nhiều bộ
có giá trị giống nhau (mỗi bộ có số phần tử bằng nhau) thì có thể chọn giá trị của một phần tử của một trong các bộ đó làm kết quả cuối cùng hoặc lấy giá trị nằm trong khoảng giá trị của phần tử các bộ đó làm kết quả cuối cùng Ví
dụ sau (có năm biến thể chương trình) sẽ minh hoạ rõ hơn về cách chọn kết quả của phương pháp Consensus:
Kết quả của các
biến thể
Kết quả sau khi quyết định
3.0
r Không chọn bằng Majority Chọn
Trang 403.0 do hai phần tử trong năm phần
tử có giá trị 3.0 (1.0,3.0,5.0,3.0,5.0) *
(1.0,2.0,3.0,4.0,5.0) Không chọn được kết quả
Ví dụ ta có hệ thống với năm biến thể chương trình có các kết quả lần lượt như sau:
1 2 3 4 5
17.5 16.0 18.1 17.5 16.0
r r r r r
Sơ đồ khối giải thuật của phương pháp quyết định Consensus được mô tả trong hình 2.12: