Để tiến thêm một bước xa hơn nữa, NVIDIA tung ra dòng sản phẩm có tên gọi Tesla,
đây là dòng sản phẩm chuyên dụng dành cho cho tính toán hiệu năng cao.
Kiến trúc tính toán và đồ họa hợp nhất Tesla đã phát triển, gia tăng đáng kể về số
lượng so với phạm vi của các GPU đồ họa không lập trình được – khả năng xử lý các
mảng dữ liệu ồ ạt đa tiến trình của nó dần trở thành một nền tảng hợp nhất hiệu năng
cao cho cả những ứng dụng tính toán đồ họa và ứng dụng tính toán song song thông
thường trên GPU.
Bằng cách chia tỉ lệ số các processors (bộ xử lý) và các thành phần bộ nhớ, kiến trúc
Tesla đã mở rộng một dải thị trường các GPU bao gồm: những GPU có hiệu năng cao
như GeForce 8800, những sản phẩm tính toán chuyên nghiệp như Quadro, Tesla và những dòng card GeForce GPU chủ đạo đa dạng về giá cả. Những đặc trưng tính toán
của các dòng card này làm cho việc lập trình với các các lõi GPU trở nên dễ dàng hơn trong môi trường lập trình C và với môi trường CUDA. Và việc nó sẵn có trong các máy laptop, desktop, workstation, và server với môi trường lập trình C và phần mềm
CUDA, đã tạo nên những nền tảng kiến trúc siêu máy tính Tesla đầu tiên ở khắp mọi
nơi.
Kiến trúc Tesla được xây dựng xung quanh một mảng có thể mở rộng của các SM (streaming multiprocessors – đa xử lý dòng lệnh). Những GPU hiện nay có thể thực
hiện từ 768 cho tới 12288 tiến trình thực thi đồng thời. Việc mở rộng qui mô thực thi
song song hóa một cách trong suốt trên một dải rộng (của các dòng GPU) sẽ là chìa khóa mục tiêu của cả kiến trúc GPU và mô hình lập trình CUDA.
Hình 5: Kiến trúc Tesla
Hình trên trình bày một GPU với 14 SMs - tương đương với 112 lõi SP (streaming processor), kết nối liên thông với 4 bộ nhớ DRAM bên ngoài. Khi một chương trình CUDA trên host CPU gọi một kernel – grid kernel (C dành cho CUDA là mở rộng của
C, nó cho phép người lập trình có thể định nghĩa các hàm C được gọi là nhân - kernel.
Và khi được gọi, nhân này sẽ được thực hiện N lần song song với nhau bởi N tiến trình
CUDA (CUDA thread) khác nhau, trái ngược với chỉ có một tiến trình được chạy như
hàm C thông thường), đơn vị phân phát công việc tính toán, gọi tắt là CWD (compute
work distribution) sẽ liệt kê các block (block – khối, trong khối này có nhiều thread, và trong một grid thì có nhiều block) của lưới và bắt đầu phân phối các block này tới
các SM với khả năng sẵn sàng thực thi (sẵn sàng chạy). Các tiến trình (thread) trong
khi các block thread kết thúc, đơn vị CWD sẽ thực thi các block mới trên các bộ xử lý
trống, rảnh rỗi.
Một SM có chứa 8 lõi xử lý vô hướng SP – scalar processor (SP), 2 đơn vị chức năng
đặc biệt – special function units (SFUs), dành cho tính toán siêu việt, 1 đơn vị dòng lệnh đa tiến trình – multithreaded instruction unit (MT IU), và 1 bộ nhớ chia sẻ trên nó
(on-chip shared memory). SM đảm nhiệm việc tạo, quản lý, và thực hiện tới 768 tiến
trình đồng thời trên phần cứng mà không tốn kém chi phí lập lịch. Nó có thể thực thi 8
block tiến trình CUDA nhiều lần và trong cùng một thời điểm, và bị giới hạn bởi số
thread và các bộ nhớ tài nguyên. SM cung cấp rào chắn CUDA __syncthreads(), rào chắn này có tác dụng đồng bộ hóa bên trong SM với một lệnh đơn. Rào chắn nhanh chóng đồng bộ cùng nhau việc tạo các tiến trình thấp hơn và sắp xếp tiến trình một
cách hiệu quả và không làm giảm hiệu năng, cho phép một thread mới được tạo để tính
toán mỗi véc-tơ, điểm ảnh và con trỏ dữ liệu.
Để quản lý hàng trăm tiến trình chạy trong nhiều ứng dụng khác nhau, Tesla SM sử
dụng một kiến trúc mới gọi là “đơn dòng lệnh đa tiến trình” – SIMT (single- instruction, multiple-thread). SM ánh xạ mỗi thread tới một lõi vô hướng SP, và mỗi
một thread vô hướng sẽ chạy độc lập với nhau với địa chỉ tập lệnh và trạng thái thanh
ghi riêng của nó. Đơn vị SM SIMT tạo, quản lý, sắp xếp và thi hành các thread trong
một nhóm gồm 32 thread song song được gọi là warps. (Thuật ngữ này bắt nguồn từ
dệt may, công nghệ song song các tiến trình đầu tiên). Các thread riêng lẻ sắp xếp theo
trật tự thành một SIMT warp khởi động cùng nhau tại cùng một địa chỉ chương trình
nhưng tự do rẽ nhánh và thực thi một cách độc lập. Mỗi SM quản lý một nhóm gồm 24
warp với 32 thread trên mỗi warp, và tổng cộng có 768 thread.
Các lệnh được đưa ra cùng một thời điểm, đơn vị SMIT sẽ lựa chọn một warp mà đã sẵn sàng thực hiện và đưa ra lệnh tiếp theo tới các thread đã được chuẩn bị trong warp.
Một warp thực thi một lệnh chung tại một thời điểm, do vậy hiệu quả cao nhất thu
chúng. Nếu các thread của một warp phân rẽ qua một dữ liệu phụ thuộc điều kiện rẽ
nhánh, thì warp sẽ thi hành từng nhánh đường dẫn lấy được, vô hiệu hóa các thread mà không ở trên đường dẫn đó, và khi tất cả các đường dẫn được hoàn thành, các thread
hội tụ trở lại để thực hiện trong cùng một đường dẫn. Sự rẽ nhánh xảy ra chỉ trong một
warp; các warp khác nhau thực thi độc lập với nhau và không chú ý tới chúng đang
thực thi một đường dẫn chung hoặc đường dẫn đoạn code rời rạc. Và kết quả là, kiến
trúc GPU Tesla đột nhiên trở nên mềm dẻo và hiệu quả hơn trên các nhánh code so với
các GPU trước đây, như các warp 32 thread của chúng bị hạn chế nhiều hơn so với độ
rộng SIMD (single-instruction multiple-data) của các GPU trước kia.
Kiến trúc SIMT gần giống với cấu trúc véc-tơ SIMD mà trong đó một lệnhđiều khiển
nhiều quá trình xử lý các phần tử. Một điều then chốt khác là cấu trúc véc-tơ SIMD bộc
lộ độ rộng với phần mềm, trong khi các lệnh SIMT định rõ việc thực thi và trạng thái
phân nhánh của một thread đơn. Trong sự trái ngược với các máy véc-tơ SIMD, SIMT
cho phép lập trình viên viết đoạn code song song phân cấp các thread một cách độc lập, các thread vô hướng, cũng như là code song song dữ liệu dành cho phối hợp các
thread. Dành cho các mục đích đúng đắn, lập trình viên có thể về căn bản lờ đi động
thái SIMT; tuy nhiên, chắc chắn hiệu năng có thể nhận thấy bởi việc chăm sóc đoạn
code ít khi yêu cầu các thread trong warp phân rẽ.
Trong thực tiễn, nó tương tự như vai trò của các dòng đệm trong code truyền thống:
kích thước dòng đệm có thể lờ đi một cách an toàn khi thiết kế với tính chất đúng đắn
nhưng phải được xem xét dưới cấu trúc đoạn code khi thiết kế cho hiệu năng tối đa.
Các kiến trúc véc-tơ, trên một hướng khác, yêu cầu phần mềm kết hợp một khối để
load trong các véc-tơ và điều khiển sự phân rẽ một cách thủ công. Một biến thread thường cư trú trong các thanh ghi đang sống. Bộ nhớ chia sẻ 16Kb SM có độ trễ truy
cập thấp và băng thông cao tương tự như bộ nhớ đệm L1; nó giữ các biến CUDA
__shared__ trên block để dành cho việc kích hoạt các block thread. SM cung cấp việc
gắn ngoài. Nó kết hợp thành một khối truy cập riêng lẻ của các thread song song trong
cùng một warp và ở trong vài truy cập block bộ nhớ khi các địa chỉ rơi vào trong cùng một block và gặp các tiêu chuẩn liên kết. Bởi vì việc trễ của bộ nhớ chung có thể tới
hàng trăm xung nhịp xử lý, các chương trình CUDA copy dữ liệu tới bộ nhớ chia sẻ
khi nó phải được truy cập rất nhiều lần bởi một block thread. Tesla nạp/lưu trữ các lệnh
bộ nhớ sử dụng địa chỉ là các byte số nguyên để thuận tiện cho trình biên dịch chuyển
đổi tối ưu các đoạn code. Tiến trình lớn đếm trong mỗi SM, cũng như là hỗ trợ cho
nhiều yêu cầu nạp còn tồn tại, giúp đỡ che phủ độ trễ trong việc nạp và sử dụng tới các
bộ nhớ DRAM gắn ngoài. Kiến trúc GPU Tesla mới nhất cũng cung cấp các lệnh bộ
nhớ đọc-sửa-ghi nguyên tử, thuận tiện cho sự giảm bớt song song và quản lý cấu trúc
song song dư liệu.
Các ứng dụng CUDA thực hiện tốt trên cácGPU kiến trúc Tesla bởi vì mô hình song
song CUDA, sự đồng bộ, các bộ nhớ chia sẻ, và phân cấp của các nhóm thread ánh xạ
hiệu quả tới các chức năng của kiến trúc GPU, và cũng bởi vì CUDA cũng là mô hình
ứng dụng song song nhanh nhất.