SC08 và GPU

 

Đối với dân trong ngành tính toán hiệu năng cao (HPC – High Performance Computing), hội nghị SC (supercomputing conference) hàng năm là nơi để gặp gỡ, trao đổi về các tiến bộ mới trong lĩnh vực máy “ngốn số liệu”. Hội nghị SC năm nay được tổ chức tại Austin, Texas là hội nghị lần thứ 20 của ngành, tính từ hội nghị đầu tiên được tổ chức tại Orlando, Florida năm 1988. Trong lần thứ 20 này, SC08 đã chứng kiến sự chuyển hướng đáng kể trong ngành HPC, từ mô hình siêu máy tính truyền thống tốn kém sang các mô hình kinh tế hơn, đặc biệt là mô hình lập trình song song trên GPU. Dưới đây tôi tóm tắt lại những sự kiện chính trong hội nghị lần này có liên quan đến GPU, mặc dù còn vô số thứ khác để học hỏi từ SC08.

  • SC08 đánh dấu sự ra đời của siêu máy tính đầu tiên trên thế giới sử dụng GPU làm công cụ tính toán hữu hiệu và kinh tế. Tôi rất lấy làm tự hào vì chiếc siêu máy tính đó đến từ Tokodai (TiTech, Tokyo Institute of Technology), nơi tôi đã có cơ hội học tập và nghiên cứu trong nhiều năm liền kể từ ngày đầu tiên bước chân lên đất Phù Tang. Với tên gọi Tsubame, hệ thống này được đặt trên tầng 2 của trung tâm tính toán và thông tin khoa học toàn cầu, nằm cạnh thư viện trung tâm ở campus O-Okayama. Bằng cách lắp đặt thêm 170 khối Tesla dạng 1U, với mỗi khối gồm 4 card Tesla, tổng cộng hệ thống có thêm 170 x 4 = 680 Tesla GPU. Sự bổ sung kịp thời này đã cho phép Tsubame vượt lên vào vị trí 29 trong bảng tổng sắp LINPACK Benmark kỳ này, với khả năng tính toán có độ chính xác kép trên số thực là 77.48 TFLOP. Với một kinh phí khiêm tốn, ít hơn rất rất nhiều lần so với hệ thống ban đầu, và với thời gian lắp đặt kỷ lục (khoảng 1 tuần lễ) nhờ sự kết hợp tuyệt vời của các kỹ sư tài năng đến từ Sun Microsystem, NEC, và NVIDIA, Tsubame với Tesla chứng tỏ khả năng sử dụng GPU trong các hệ thống HPC là hoàn toàn hiện thực. Tokodai sẽ chào đón sự kiện này bằng một ngày đặc biệt, đúng vào thứ ba tuần sau 02/12 tại O-Okayama Campus. Bạn nào ở Nhật và có thời gian vui lòng đến dự cho vui.
  • SC08 chứng kiến sự hợp tác toàn diện giữa NVIDIA và NEC. Chắc chắn trong thời gian sắp tới, chúng ta sẽ được thưởng thức nhiều sản phẩm ngoạn mục dựa trên CUDA mà NEC mang lại cho người dùng mức cao.
  • Phần mềm huyền thoại Mathematica với phiên bản 7.0 chính thức hỗ trợ tự động tính toán song song trên các hệ thống đa lõi, và phiên bản “CUDA-enabled” sẽ được phát hành vào tháng Giêng năm 2009. Chúng ta cùng xem Wolfram Research nói gì về CUDA:

“Since its initial release, Mathematica has been adopted by over 3 million professionals across the entire global technical computing community, and it has had a profound effect on how computers are used across many fields,” said Joy Costa, director of global partnerships at Wolfram Research. “The prospect of a hundred fold increase in Mathematica 7 performance is staggering. CUDA enabled Mathematica will revolutionize the world of numerical computation.

  • Không những chỉ có các dàn máy khổng lồ, SC08 là nơi ra đời của một khái niệm mới, “Personal Supercomputer (PSC)”. Nếu trong thập niên 80, những chiếc máy PC của IBM đã tạo nên một cuộc cách mạng máy tính với công thức “Một người dùng – một PC”, thì hôm nay, với Tesla/Quadro GPU của NVIDIA, chúng ta có “Một nhà nghiên cứu, một PSC”. Cấu hình thông dụng của các PSC mà tôi có dịp tham gia lắp đặt gần đây bao gồm 1 card Quadro FX5800 phục vụ hiển thị đồ họa cùng 3 card Tesla C1060 phục vụ tính toán. Sự kết hợp này mang lại cho chúng ta khoảng 4 TFLOP khả năng tính toán trên số thực với độ chính xác đơn, cùng với hệ thống bộ nhớ 16GB DDR2, với giá thành khoảng 10,000 USD, rẻ hơn 100 lần so với một hệ máy có cùng khả năng tính toán sử dụng giải pháp CPU cluster, chưa kể đến không gian nhỏ gọn của chỉ một thùng máy lớn, thay vì cả một gian phòng, và chi phí điện năng hết sức tiết kiệm.

Tính toán song song trên dữ liệu – Phần 1 : Điểm xuất phát

Tiếp theo phần giới thiệu hôm trước, hôm nay tôi sẽ tóm tắt tiếp phần 1 có tựa đề là “A bit of background” trong bài báo của Chas. Tôi đặt lại tựa phần này là “Điểm xuất phát” cho dễ hiểu.

Ở đây để giảng giải lý do cần thiết cho tính khuếch trương của một phần mềm hiện đại, Chas đã chỉ ra rằng:

  • Sự phát triển hiệu năng của bộ xử lý bị giới hạn bởi các quy luật vật lý cơ bản. Với những quy luật này, trong thập niên 90 của thế kỷ 20, chúng ta đã được chứng kiến nhiều cải tiến kỹ thuật cho bộ xử lý, ví dụ như tăng số cổng trên mỗi chip, rồi tăng tốc độ đồng hồ hệ thống, hay kỹ thuật tạo xử lý song song ở mức chỉ thị máy (instruction-level parallelism, viết tắt là ILP). Tuy nhiên những năm gần đây (kể từ 2003 trở đi), cũng chính các quy luật vật lý đó đã dần dần đặt dấu chấm hết cho những cải tiến như vậy, chẳng hạn như:
    • Với kỹ thuật tăng tốc đồng hồ hệ thống: các giới hạn về năng lượng và nhiệt đã gần đạt đến mức không thể chấp nhận được. Điều này có nghĩa là chúng ta sẽ không còn thấy nhiều sự nhảy vọt ở mức GHz như đối với MHz nhiều năm về trước. Hiện tại bộ xử lý đang dậm chân trong khoảng từ 3 ~ 5GHz về mặt tốc độ.
    • Với kỹ thuật tạo xử lý song song ở mức chỉ thị máy: các giới hạn về diện tích chip khiến việc gia tăng xử lý kiểu này thông qua dự đoán rẻ nhánh (branch prediction) hay thực thi kiểu đầu cơ (speculative execution) hay nhiều thứ hay ho cao siêu khác nữa đã trở thành dĩ vãng.
  • Còn một yếu tố duy nhất có thể cải tiến là số lượng cổng trên chip. Càng có nhiều cổng trên một chip có nghĩa là càng có nhiều nhân hay lõi được tạo ra. Số lượng nhân trên mỗi chip được dự đoán sẽ lại tăng gấp đôi sau mỗi 2 năm, tức là khoảng 2012 chúng ta sẽ thấy CPU có 32 nhân. Dĩ nhiên là người dùng sẽ rất hạnh phúc, vì cùng với một khoảng tiền như trước, họ có nhiều CPU con trong máy hơn. Tuy nhiên, tất cả đều chỉ sẽ thật sự hạnh phúc khi phần mềm cũng có khả năng mở rộng hiệu năng theo đà phát triển đó, và mọi chuyện lại sẽ như ngày xưa, khi chúng ta chỉ cần đổi máy mới hay nâng cấp máy là mọi thứ sẽ chạy ngon lành hơn trước.

Tính toán song song trên dữ liệu: – Phần 2: Lập trình song song kiểu cổ điển

Trong phần 2 với tựa đề “Parallel prorgamming”, bằng cách nêu lên 3 khó khăn chủ đạo trong mô hình lập trình song song truyền thống là:

  • Cách suy nghĩ tuần tự của lập trình viên
  • Khả năng mở rộng hiệu năng (performance scaling)
  • Sự chuyển đổi thuật toán từ tuần tự sang song song hết sức tốn kém về thời gian và nhân lực

Chas đã dẫn dắt người đọc đến với yêu cầu về một mô hình lập trình song kiểu mới linh hoạt hơn và theo sát với sự thay đổi về số lượng nhân /lõi của một hệ thống máy tính.

Chúng ta hãy thử cùng tác giả tìm hiểu chi tiết hơn về 3 khó khăn nói trên xem sao.

* Khó khăn thứ nhất – Suy nghĩ tuần tự

Tôi còn nhớ như in ngày đầu tiên tôi được học lập trình trên chiếc máy tính XT cổ lỗ sĩ ở trường Tổng hợp cách đây gần 18 năm. Thầy hướng dẫn ra lệnh cho đám nhốn nháo TH1 lần đầu tiên được ngồi cạnh máy tính gõ từng lệnh của một chương trình viết bằng ngôn ngữ Pascal, trên bộ soạn thảo tích hợp Turbo Pascal. Hồi đó máy tính còn là một thứ hết sức quý hiếm với dân Sài gòn, đặc biệt là với sinh viên nghèo như tụi tui, nên giờ thực hành bà con hết sức chăm chỉ ngồi “gõ” chương trình. Ai có tiền hơn thì đi thuê phòng máy ở ngoài để “gõ” trước, rồi vô giờ thực hành tranh thủ nhờ thầy cô sửa lỗi giùm. Mà ngay cả đi thuê máy cũng khó khăn, phải đăng ký trước, rồi mỗi người chỉ được thuê 1, 2 tiếng chẳng hạn. Cho nên sinh viên tin học thời đó rất siêu môn gọi là “chạy chương trình chay” trên giấy, nghĩa là tự viết chương trình hết sức rõ ràng đầy đủ trên giấy (chứ còn chưa có bản in kim nữa là), rồi cùng nhau chạy bằng “miệng”, lẩm nhẩm từng bước một, ghi kết quả ra giấy để coi đúng không. Giờ nghĩ lại hồi đó làm vậy được là vì chương trình được viết ra để chạy tuần tự theo kiểu kiến trúc đơn luồng von Neumann, hết lệnh này tới lệnh khác (nói chữ nghĩa hơn là “có tính tất định” – deterministic), nên biết chắc được kết quả ở từng bước nếu mình không chạy sai về thứ tự thực thi. Cũng chính vì thói quen suy nghĩ tuần tự đã ăn sâu như vậy nên giờ chuyển sang suy nghĩ kiểu song song rất là mệt mỏi, vì sẽ phải chú ý tới các lỗi đặc thù của nó, nào là khóa chết (deadlock), rồi khóa sống (livelock), rồi điều kiện cạnh tranh, … rất khó nhận biết, và quan trọng hơn là các lỗi này thường không lập lại được để biết coi nguyên nhân từ đâu (tiếng Anh gọi là nonrepeatable error) để sửa chữa. Ngành khoa học máy tính đã tốn vài chục năm vừa rồi để đề ra nhiều phương pháp giải quyết, nhưng chưa đâu vào đâu cả.

Suy nghĩ kỹ hơn chúng ta có thể thấy rằng vụ tư duy tuần tự này là do môi trường lập trình quyết định. Từ thập niên 80 đến khoảng gần đây, chúng ta chủ yếu làm việc với máy tính cá nhân, và mô hình thực thi trên đó như đã nói là từng bước một. Cũng có máy tính song song, nhưng hiếm người được dùng nó trong công việc hàng ngày, vì chuyện xây dựng một hệ máy tính như vậy ở mức quốc gia đã cực kỳ tốn kém chứ đừng nói là công ty hay cá nhân. Còn bản thân con người hoàn toàn không xa lạ gì với chuyện ứng dụng xử lý song song trong đời sống hàng ngày. Dân tin học mê kiếm hiệp tụi tui vẫn nói đùa là Châu Bá Thông là ông tổ lập trình song song, do hai tay có thể thi triển hai loại võ công tuyệt thế khác nhau cùng lúc. Hay khi mình đi siêu thị mua đồ rồi trả tiền, thay vì phải xếp một hàng dài, bà con nghĩ liền đến chuyện lập nhiều quầy thu ngân cùng lúc cho lẹ. Hoặc đường cao tốc có nhiều làn xe là một ví dụ tương tự nữa minh họa hết sức rõ ràng về xử lý song song. Đó là ở quy mô xã hội. Còn với mỗi người, chuyện tranh thủ làm nhiều thứ cùng lúc cũng là bình thường, ví dụ như bấm nồi cơm điện, bắt ấm nước sôi, rồi tranh thủ rửa chén, ba cái sẽ xong cùng một lúc. Rõ ràng mình có thể liệt kê rất nhiều ví dụ nữa kiểu như vậy.

* Khó khăn thứ hai – Mở rộng hiệu năng

Qui tắc Amdahl trong lập trình song song cho chúng ta biết là lượng tăng tốc tối đa có thể đạt được bằng việc song song hóa thuật toán thì tỷ lệ nghịch với phần mã chương trình không thể chuyển sang dạng song song. Nói nôm na là cho dù chỉ còn 10% mã chương trình không thể song song hóa, thì sự tăng tốc chương trình đó cũng không vượt quá 10 lần. Tuy nhiên để ướng lượng mức độ cải tiến theo kiểu này rất khó, vì không thể xác định chính xác bao nhiêu phần trăm mã chương trình thật sự chạy song song, do trong lúc thực thi song song, mọi thứ lại rất có thể bị chuyển ngược lại thành tuần tự, như khi có tranh chấp tài nguyên dùng chung, hay có truy cập đến nhiều vị trí khá cách xa nhau trong bộ nhớ. Đây chính là một trong những hạn chế chính của mô hình lập trình song truyền thống (vốn thường cài đặt cách điều khiển tiểu trình qua cơ chế khóa, hay qua giao diện truyền thông điệp, hay nhiều cách khác nữa đòi hỏi sự đồngbộ hóa – nói nôm na là tiểu trình này đợi tiểu trình kia hoàn tất công việc rồi mới làm tiếp phần việc tiếp theo của mình) khi áp dụng cho nhiều nhân/lõi. Nói một cách dễ hiểu, nếu chúng ta chỉ phải đợi từng người một hoàn tất công việc của họ một cách độc lập, thì thời gian chờ đợi có thể coi là tăng tuyến tính với số người cần đợi/đồng bộ. Nhưng nếu chúng ta phải đợi cùng lúc nhiều người, và kết quả công việc của họ lại phụ thuộc lẫn nhau, thì thời gian chờ đợi sẽ tăng tổ hợp và rất khó xác định, chứ không đơn giản chỉ là tăng tuyến tính.

Còn có một khó khăn cơ bản hơn nữa trong mở rộng hiệu năng với số nhân/lõi. Mô hình lập trình song song truyền thống tiếp cận bài toán cần giải quyết theo kiểu top-down, bằng cách chia một bài toán lớn thành nhiều tác vụ con, và mỗi tác vụ này sẽ được giao cho một bộ xử lý/nhân/lõi. Vấn đề rắc rối ở đây là khi số lượng bộ xử lý/nhân/lõi tăng lên đến hàng chục, hay hàng trăm như hiện nay, thì số tác vụ con đã được thiết kế để giao nhằm tận dụng sức mạnh tính toán của chúng lại không có đủ.
Cách tiếp cận phổ biến nhất cho tình huống này là lại cố chia nhỏ các tác vụ con đó thành nhiều đơn vị thực thi nhỏ hơn.
Như vậy, cách làm này bị phụ thuộc vào từng thế hệ phần cứng bộ xử lý, dẫn đến chuyện không thể mở rộng việc thực thi chương trình một cách dễ dàng theo kiểu không cần phải thay đổi, sửa chữa gì về mặt thuật toán hay mã nguồn cài đặt. Và suy cho cùng thì nếu một bài toán mà được chia thành vài chục tác vụ con chạy song song sẽ vô cùng khó quản lý và gỡ rối.

* Khó khăn thứ ba – Tuần tự sang song song

Chuyện đau khổ nhất trong việc cố gắng chuyển mã từ tuần tự sang song song dựa trên tác vụ là ở chỗ quá trình này cần rất nhiều thời gian, có khi cả vài năm trời. Do tốc độ gia tăng số nhân/lõi hiện tại quá nhanh, nên nhiều khi thuật toán song song mà chúng ta đã bỏ ra vài năm kể từ năm nay để thiết kế lại không mở rộng tốt với số nhân/lõi của vài năm nữa, ở thời điểm chúng ta hoàn tất việc cài đặt nó một cách song song. Vậy là coi như mọi cố gắng sẽ thành công cốc!!!

Thật ra ý tưởng gán một công việc nhỏ cho từng bộ xử lý/nhân/lõi trong máy tính nhằm tăng hiệu năng phần mềm chạy trên đó là hoàn toàn tự nhiên và được đúc kết từ kinh nghiệm trong đời sống hàng ngày. Tuy nhiên để tận dụng được hết sức mạnh của hàng trăm, rồi hàng ngàn nhân/lõi trong tương lai, chúng ta có lẻ cần phải “đi trước đón đầu” bằng cách tạo ra hàng chục ngàn, hàng trăm ngàn công việc nhỏ li ti cung cấp cho đội quân nhân/lõi đông đảo và ngày một gia tăng đó. Ở đâu ra  một khối lượng lớn các “tiểu tác vụ” như vậy?

Lời giải nằm ở chỗ bạn đừng quan tâm đến số lượng các tác vụ cần thực hiện, mà hãy để mắt đến khối lượng dữ liệu mà bạn cần xử lý. Chẳng hạn, có nhiều nhất bao nhiêu điểm ảnh có thể xử lý độc lập với một ảnh HD 1920 x 1080?