• Thứ Ba, 12/12/2006 14:23 (GMT+7)

    Cuộc cách mạng song hành

    Một cuộc cách mạng lớn nhất trong lĩnh vực phát triển phần mềm - kể từ cuộc cách mạng hướng đối tượng - hứa hẹn tăng tốc cho ứng dụng, nhưng cũng có cái giá phải trả.

    Một cuộc cách mạng lớn nhất trong lĩnh vực phát triển phần mềm - kể từ cuộc cách mạng hướng đối tượng - hứa hẹn tăng tốc cho ứng dụng, nhưng cũng có cái giá phải trả...

    Các đại gia sản xuất bộ xử lý (BXL), từ Intel và AMD đến Sparc và PowerPC, đang từ bỏ những phương thức tăng tốc CPU truyền thống. Thay vì chạy đua tốc độ xung nhịp và số lệnh xử lý ngày càng cao hơn, các hãng đổ dồn sang kiến trúc đa nhân (multicore) và siêu luồng (hyperthreading). Cả hai kiến trúc này đều đã hiện diện trong các chip hiện có trên thị trường; riêng kiến trúc đa nhân đã được sử dụng trong các BXL PowerPC và Sparc PC IV hiện tại, và sẽ xuất hiện trong các BXL Intel và AMD trong năm nay (2005).

    Điều này tạo nên bước ngoặt quan trọng trong lĩnh vực phát triển phần mềm, ít nhất là đối với các ứng dụng cho máy tính để bàn và máy chủ cấp thấp (chiếm phần lớn doanh thu phần mềm hiện nay). Tại sao sự thay đổi kiến trúc phần cứng lại tác động đến phần mềm, và sự thay đổi này có ý nghĩa đặc biệt như thế nào và sẽ tác động như thế nào đến cách thức phát triển phần mềm trong tương lai?

    Tốc độ miễn phí

    Có một câu truyền tụng thú vị: “Andy cho và Bill lấy đi” (Andy Grove nguyên là chủ tịch Intel và Bill Gates là chủ tịch Microsoft, đây là hai hãng sản xuất BXL và phần mềm hàng đầu hiện nay). Dù BXL có tăng tốc nhanh đến mấy đi nữa thì phần mềm luôn tìm được cách để tiêu thụ tốc độ gia tăng được. Hàng chục năm nay, hầu hết các ứng dụng đều được hưởng lợi tăng tốc độ đều đặn và miễn phí, thậm chí không cần phải đưa ra phiên bản mới hay thực hiện thay đổi gì đặc biệt, nhờ các nhà sản xuất CPU (chủ yếu) và các nhà sản xuất bộ nhớ và đĩa cứng luôn đảm bảo cung cấp các hệ thống mới ngày càng nhanh hơn. Tốc độ xung nhịp không phải là giải pháp duy nhất cho tốc độ nhưng là giải pháp chủ đạo: chúng ta đã từng chứng kiến CPU 500MHz nhường bước CPU 1GHz rồi CPU 2GHz... Hiện nay, dòng CPU 3GHz đang trở lên thịnh hành.

    Khi nào thì việc gia tăng tốc độ sẽ dừng lại? Định luật Moore tiên đoán sự gia tăng theo số mũ rõ ràng không thể tiếp tục mãi khi chúng ta đạt đến giới hạn vật lý. Việc tăng tốc độ rồi sẽ chậm lại và có thể dừng lại. (Chú thích: định luật Moore chủ yếu áp dụng cho mật độ transistor, tuy nhiên việc tăng theo cấp số mũ tương tự cũng xảy ra trong các lĩnh vực liên quan như tốc độ xung nhịp. Thậm chí trong những lĩnh vực khác còn gia tăng nhanh hơn, chẳng hạn như lưu trữ dữ liệu).

    Nếu làm công việc phát triển phần mềm, nhiều khả năng bạn đã hưởng lợi trên tốc độ của máy tính. Chương trình của bạn bị giới hạn tốc độ trong một số tác vụ? Không cần bận tâm, các BXL mới sẽ đẩy nhanh tốc độ, mặc dù các chương trình hiện nay thường chịu sự chi phối của những yếu tố khác ngoài tốc độ CPU và bộ nhớ (ví dụ như phụ thuộc vào cơ sở dữ liệu, tác vụ ngoại vi, mạng). Điều này đúng trước đây nhưng sẽ không còn đúng trong thời gian tới.

    Tin tốt là các BXL tiếp tục ngày càng mạnh hơn. Tin xấu là, ít nhất trong tương lai gần, việc tăng tốc sẽ chủ yếu theo hướng không “nâng đỡ” cho hầu hết ứng dụng hiện nay.

    Hơn 30 năm qua, các nhà thiết kế CPU đã thực hiện gia tăng tốc độ trong 3 lĩnh vực chính, hai trong số đó tập trung vào tiến trình thực thi lệnh:

    Tốc độ xung nhịp

    Tối ưu việc thực thi

    Bộ nhớ đệm (cache)

    Việc gia tăng tốc độ xung nhịp cho nhiều chu kỳ xung hơn. Chạy CPU nhanh hơn gần như đồng nghĩa với việc thực hiện công việc nhanh hơn. Việc tối ưu khả năng thực thi cho phép làm được nhiều việc hơn trong mỗi chu kỳ. Các CPU hiện nay có tập lệnh mạnh hơn và thực hiện đủ loại tối ưu từ cơ bản đến phức tạp như tạo tuyến ưu tiên, tiên đoán rẽ nhánh, thực thi nhiều lệnh trong cùng xung nhịp; thậm chí còn sắp xếp lại chuỗi lệnh để cho phép thực thi không theo trình tự. Các kỹ thuật này đều được thiết kế nhằm làm cho tiến trình thực thi tốt hơn và nhanh hơn, tận dụng tối đa từng chu kỳ xung nhịp.

    Ở đây xin nói thêm về việc sắp xếp lại lệnh thực thi: đôi khi việc này không thật sự tối ưu, nó có thể làm thay đổi chương trình và đưa đến những kết quả khác mong đợi của lập trình viên. Các nhà thiết kế CPU không hề muốn làm tổn hại chương trình của bạn... thường là như vậy. Nhưng gần đây, họ đã cố gắng tối ưu quá mức nhằm thực hiện nhiều lệnh hơn trong từng chu kỳ xung, vì vậy có thể gây phản tác dụng!

    Cuối cùng là việc tăng dung lượng bộ nhớ đệm (cache) trên chip. Bộ nhớ chính (RAM) vẫn còn chậm hơn nhiều so với CPU vì vậy việc đưa dữ liệu đến gần BXL càng có ý nghĩa. Dung lượng cache trên BXL đã tăng vọt, hiện hầu hết CPU đều được trang bị cache L2 từ 2MB trở lên. Trong 3 phương thức tăng tốc CPU truyền thống, việc tăng cache là phương thức duy nhất sẽ được tiếp tục trong thời gian tới.

    Việc tăng tốc bất kỳ yếu tố nào trong 3 yếu tố trên cũng đều dẫn đến việc tăng tốc ứng dụng. Dĩ nhiên, trình biên dịch phải cập nhật; đôi khi bạn cần phải biên dịch lại ứng dụng nhằm khai thác các tập lệnh mới (ví dụ như MMX, SSE) và một số đặc tính mới của CPU. Tuy nhiên, thường thì ngay cả các ứng dụng cũ cũng luôn chạy nhanh hơn mà không phải biên dịch lại.

    “Cuộc sống” đã thật dễ dàng. Không may, sự hào phóng trước đây nay đã hết.

    Tại sao chưa có CPU 10GHz?

    Việc tăng tốc CPU đã đạt đến ngưỡng giới hạn cách đây 2 năm. Chỉ đến gần đây nhiều người mới nhận thức được điều này. Ở đây chúng ta sẽ xem xét dữ liệu của Intel. Hình 1 là biểu đồ chip Intel theo tốc độ xung và số transistor. Số transistor tiếp tục tăng, ít nhất đến thời điểm hiện nay. Tuy nhiên, tốc độ xung thì lại khác.

    Từ mốc khoảng đầu năm 2003, bạn thấy có sự chuyển hướng rõ ràng so với chiều hướng tăng tốc xung nhịp trước đó. Thay vì tiếp tục đường đi lên theo chiều hướng trước đây (thể hiện bởi đường đứt nét), đường tốc độ chuyển sang nằm ngang. Ngày càng khó đạt tốc độ xung cao hơn do nhiều yếu tố vật lý, chẳng hạn như nhiệt, tiêu thụ điện năng và rò rỉ dòng.

    Theo chiều hướng tăng tốc của chip Intel trước năm 2003 thì đến năm 2005 này chúng ta đã có chip Pentium 10GHz. Thế nhưng hiện nay thậm chí chúng ta chẳng nghe nói đến kế hoạch sản xuất chúng. (Vào thời điểm thực hiện bài viết này, Intel mới có kế hoạch đưa ra chip 3,73GHz trong đầu năm 2005). Thật sự, cuộc đua tốc độ xung nhịp đã kết thúc, ít nhất là trong thời gian này; Intel và hầu hết các hãng sản xuất BXL khác đang đổ dồn sang hướng đa nhân.

    Định luật Moore và những thế hệ BXL mới

    Liệu định luật Moore có kết thúc? Nói chung là không. Dĩ nhiên, một ngày nào đó định luật Moore cũng phải kết thúc, nhưng có vẻ như nó vẫn đứng vững trong vài năm tới. Mặc dù tốc độ xung đã va phải bức tường, nhưng số lượng transistor sẽ vẫn tiếp tục tăng và có vẻ như CPU vẫn sẽ tiếp tục tăng tốc theo định luật Moore trong vài năm tới.

    Sự khác biệt quan trọng đó là sự gia tăng hiệu suất BXL sẽ đi theo hướng khác và hầu hết ứng dụng hiện tại sẽ không được tận hưởng nếu không thiết kế lại.
    Trong vài năm tới, hiệu suất gia tăng trong các chip mới sẽ chủ yếu nhờ 3 yếu tố, chỉ 1 trong số đó còn sót lại của quá khứ:

    Siêu luồng (HT – HyperThreading)

    Đa nhân (multicore)

    Bộ nhớ đệm (cache)

    Siêu luồng có nghĩa là thực thi nhiều tiến trình đồng thời trong 1 CPU. Các CPU siêu luồng (HT-CPU) hiện đã có trên thị trường, chúng cho phép một số lệnh chạy đồng thời. Tuy nhiên, có một điểm hạn chế, đó là mặc dù HT-CPU có thêm một số phần cứng như các thanh ghi bổ sung nhưng nó vẫn chỉ có 1 cache, 1 đơn vị xử lý toán học, 1 đơn vị xử lý số thực, nói chung là các tính năng cơ bản nhất của CPU chỉ có 1. HT thường được cho là giúp tăng tốc 5-15% cho các ứng dụng HT, hay thậm chí 40% trong điều kiện lý tưởng đối với ứng dụng được thiết kế đa luồng. Tốt, nhưng khó đạt được gấp đôi và nó không có ích gì cho các ứng dụng đơn trình (chỉ có 1 tiến trình).

    Đa nhân nghĩa là có nhiều CPU trên 1 chip. Một số chip, như Sparc và PowerPC, đã có các phiên bản đa nhân. Các phiên bản chip đầu tiên của Intel và AMD, dự kiến ra mắt trong năm 2005, khác về mức độ tích hợp nhưng chức năng tương tự. AMD có vẻ như có một số ưu thế ban đầu như tích hợp các chức năng hỗ trợ tốt hơn, trong khi đó bước khởi đầu của Intel về cơ bản chỉ là “nhét” 2 CPU Xeon vào 1 chip. Sự gia tăng hiệu suất ban đầu giống như hệ thống 2 CPU (chỉ có điều giá sẽ rẻ hơn vì bo mạch chủ không cần 2 đế cắm và các chip liên quan), nhưng không đạt mức gấp đôi ngay cả trong trường hợp lý tưởng, và cũng như hiện nay, nó tăng tốc đáng kể cho những ứng dụng được thiết kế đa trình tốt. Nhưng các ứng dụng đơn trình thì không.

    Cuối cùng, dung lượng cache trên chip được kỳ vọng tiếp tục tăng, ít nhất trong tương lai gần. Trong 3 yếu tố, chỉ có yếu tố này có ích cho hầu hết ứng dụng hiện tại. Sự gia tăng liên tục dung lượng cache là một thuận lợi vô cùng cho nhiều ứng dụng. Trên các hệ thống hiện nay, việc truy cập bộ nhớ chính thường chậm hơn 10-50 lần so với cache; điều này có thể làm ngạc nhiên nhiều người vì bộ nhớ luôn được nghĩ là nhanh, quả thực nó nhanh so với đĩa và mạng, nhưng không thể so với cache trên chip vốn hoạt động ở tốc độ nhanh hơn. Thật tuyệt nếu cache đủ chứa đoạn mã làm việc của ứng dụng. Đó là lý do dung lượng cache gia tăng sẽ thổi thêm luồng sinh khí và kéo dài tuổi thọ cho một số ứng dụng hiện tại mà không phải chỉnh sửa gì đáng kể: khi các ứng dụng hiện tại xử lý ngày càng nhiều dữ liệu, và khi chúng được bổ sung mã lệnh cho những chức năng mới, các tác vụ đòi hỏi tốc độ cần tiếp tục chứa vừa trong cache.

    Cache làm tốt vai trò của nó. Còn CPU đa nhân và HT sẽ gần như không có ảnh hưởng gì đối với hầu hết ứng dụng hiện nay. Vậy sự thay đổi này trong phần cứng có ý nghĩa gì đối với cách thức chúng ta viết phần mềm?

    Cuộc cách mạng kế tiếp trong phát triển phần mềm

    Vào thập nhiên 1990, chúng ta học để nắm vững đối tượng. Cuộc cách mạng trong lĩnh vực phát triển phần mềm từ lập trình cấu trúc sang lập trình hướng đối tượng (OO - Object Oriented) là bước phát triển lớn nhất trong vòng 20-30 năm. Đã có những bước phát triển khác, như sự ra đời của dịch vụ web gần đây, nhưng đều không tác động một cách cơ bản và sâu sắc đến cách thức chúng ta viết phần mềm như cuộc cách mạng đối tượng. Cho đến hiện tại.

    Từ nay, tốc độ không còn miễn phí nữa. Chắc chắn, sẽ vẫn tiếp tục có những cải tiến tốc độ để mọi người khai thác, chủ yếu nhờ vào việc tăng dung lượng cache. Nhưng nếu bạn muốn khai thác tốc độ tiếp tục tăng theo cấp số mũ của các BXL mới, thì cần phải phát triển ứng dụng theo kỹ thuật song hành (thường là đa trình). Điều này nói dễ hơn làm, bởi vì không phải mọi vấn đề đều có thể thực hiện song hành và hơn nữa việc lập trình song hành không dễ.

    Hẳn sẽ có lời phản đối: “Song hành không mới! Người ta đã lập trình song hành từ lâu”. Điều này đúng, nhưng chỉ với một bộ phận nhỏ nhà phát triển.

    Nên nhớ rằng người ta đã lập trình hướng đối tượng ít nhất từ thời Simula vào cuối thập niên 1960. Tuy nhiên phải đến tận thập niên 1990 kỹ thuật OO mới trở nên phổ biến và tạo nên cuộc cách mạng thật sự. Tại sao vậy? Cuộc cách mạng trong ngành công nghiệp phần mềm diễn ra chủ yếu là do nhu cầu xây dựng các hệ thống ngày càng lớn hơn để giải quyết những bài toán ngày càng phức tạp và khai thác tài nguyên CPU và lưu trữ ngày càng mạnh hơn.

    Trong thập niên qua, ngày càng có nhiều người lập trình song hành. Tuy nhiên một cuộc cách mạng thật sự với sự chuyển đổi hàng loạt sang lập trình song hành vẫn chưa đến. Hiện nay, đa phần ứng dụng vẫn là đơn trình.

    Song hành, nhanh nhưng không dễ

    Có 2 nguyên nhân chính dẫn đến việc sử dụng song hành, đặc biệt là HT, trong phần mềm. Thứ nhất, bản chất các luồng điều khiển độc lập tách biệt nhau về mặt luận lý. Thứ hai, song hành đem đến sự cải thiện hiệu suất, hoặc nhờ tận dụng nhiều CPU hoặc thời gian “chết” của các tiến trình trong ứng dụng.

    Tuy nhiên, song hành có cái giá của nó. Trước hết, không phải tất cả ứng dụng đều có thể thực hiện song hành. Và trở ngại lớn nhất là việc lập trình song hành khó hơn nhiều so với lập trình theo trình tự quen thuộc trước đây.

    Thách thức mà lập trình viên cấu trúc khi chuyển sang OO (đối tượng là gì? làm thế nào sử dụng kế thừa?...) từng gặp cũng là thách thức tương tự cho lập trình viên tuần tự khi chuyển sang song hành (luồng thực thi là gì? tắc nghẽn là gì? làm thế nào giải quyết hoặc tránh nó? những tiến trình nào có thể thực hiện song hành...). Đa số lập trình viên hiện nay không am hiểu kỹ thuật song hành, cũng như cách đây 15 năm đa số lập trình viên không am hiểu kỹ thuật hướng đối tượng (OO). Tuy nhiên, mọi thứ đều có thể học được.

    Giờ chính là lúc bạn và đội ngũ phát triển phần mềm của mình nên bắt tay vào tìm hiểu kỹ thuật song hành và nghiên cứu thiết kế ứng dụng theo hướng song hành. Chỉ có như vậy ứng dụng của bạn mới có thể khai thác tốc độ tiếp tục gia tăng theo cấp số mũ của các BXL mới.

     

    LÝ THUYẾT VÀ THỰC TẾ: 2 x 3GHz < 6GHz

     
     

    CPU kết hợp 2 nhân 3GHz có năng lực xử lý tương đương 6GHz? Sai. Thậm chí khi có 2 tiến trình chạy trên 2 BXL vật lý cũng không có nghĩa là đạt được tốc độ gấp đôi. Tương tự, hầu hết các ứng dụng đa trình không thể thực thi nhanh gấp đôi trên BXL nhân đôi. Tốc độ không tăng tuyến tính.
    Tại sao? Trước hết, có sự thoả hiệp giữa các nhân nhằm đảm bảo cache không bị tranh chấp và để thực hiện việc liên kết giữa các tiến trình. Hiện nay, một hệ thống 2 hay 4 BXL không hẳn nhanh gấp 2 hay 4 lần hệ thống 1 CPU, ngay cả với các ứng dụng đa luồng. Vấn đề này cũng tương tự với các CPU đặt chung trên 1 chip.
    Thứ hai, trừ phi 2 nhân chạy các tiến trình khác nhau, hay các tiểu trình khác nhau của 1 tiến trình được xây dựng để chạy một cách độc lập và gần như không bao giờ chờ đợi tiến trình (hay tiểu trình) nào khác, còn không thì hệ thống sẽ không làm việc hiệu quả. (Có thể các ứng dụng đơn trình hiện nay làm việc nhanh hơn trên hệ thống nhân đôi, nhưng không phải nhờ nhân bổ sung làm điều gì đó có ích mà vì nó chạy phần mềm gián điệp và quảng cáo lây nhiễm trên hệ thống của nhiều người dùng và đây là nguyên nhân làm chậm hệ thống 1 CPU hiện tại!).
    Nếu bạn đang dùng ứng dụng đơn trình thì chỉ cần 1 CPU. Có thể hệ thống nhanh hơn đôi chút khi HĐH và ứng dụng chạy trên các nhân riêng biệt, nhưng thường thì HĐH không khai thác hết năng lực CPU, vì vậy một trong hai nhân sẽ thường xuyên rỗi.

     

    Phương Uyên
    DDJ 2005

    ID: A0503_88