Lập lịch lệnh (instruction scheduling) là phép tối ưu ở giai đoạn sinh mã cuối, nhằm sắp xếp thứ tự/thời điểm phát hành các lệnh trên một kiến trúc pipeline sao cho tôn trọng các ràng buộc phụ thuộc dữ liệu (data hazard), ví dụ độ trễ (latency) giữa một lệnh nạp dữ liệu (load) và lệnh sử dụng kết quả của nó. Bài này yêu cầu tính thời điểm bắt đầu sớm nhất (earliest start time) của từng lệnh và tổng số chu kỳ (cycle) cần thiết, giả sử có đủ tài nguyên phần cứng để thực thi song song (không giới hạn số lệnh phát hành đồng thời), chỉ bị ràng buộc bởi phụ thuộc dữ liệu.
Cho n lệnh (đánh số 0,…,n−1), lệnh i có thời lượng thực thi di≥1 chu kỳ. Có m ràng buộc phụ thuộc dạng (u,v,lat), nghĩa là lệnh v chỉ được phép bắt đầu khi lệnh u đã bắt đầu được ít nhất lat chu kỳ, tức start(v)≥start(u)+lat (giá trị lat có thể nhỏ hơn du, mô phỏng việc lệnh v có thể bắt đầu trước khi u hoàn tất, nếu kiến trúc cho phép pipeline). Dữ liệu đảm bảo tập ràng buộc tạo thành một đồ thị có hướng không chu trình (DAG).
Thời điểm bắt đầu sớm nhất của mỗi lệnh được tính bằng: start(v)=max(0, max(u,v,lat) laˋ một raˋng buộc(start(u)+lat)) (lệnh không có ràng buộc nào bắt đầu ở chu kỳ 0).
Tổng số chu kỳ cần thiết (makespan) là thời điểm hoàn tất của lệnh kết thúc muộn nhất: makespan=maxi=0,…,n−1(start(i)+di)
Ví dụ: 3 lệnh với d=(2,3,1) và hai ràng buộc (0,1,2), (1,2,3): start(0)=0, start(1)=max(0,0+2)=2, start(2)=max(0,2+3)=5; makespan =max(0+2, 2+3, 5+1)=6.
Dòng đầu tiên chứa hai số nguyên n, m (1≤n≤500, 0≤m≤5000).
Dòng thứ hai chứa n số nguyên d0,d1,…,dn−1 (1≤di≤1000).
m dòng tiếp theo, mỗi dòng ba số nguyên u, v, lat (0≤u,v<n, u=v, 0≤lat≤1000) mô tả ràng buộc start(v)≥start(u)+lat. Đảm bảo các ràng buộc tạo thành DAG.
In ra n dòng đầu: dòng thứ i (i=1,…,n) là start(i−1) — thời điểm bắt đầu sớm nhất của lệnh i−1. Dòng cuối cùng (dòng thứ n+1) in ra giá trị makespan (tổng số chu kỳ cần thiết) như định nghĩa ở trên.
Ví dụ:
Đầu vào:
3 2
2 3 1
0 1 2
1 2 3
Đầu ra:
0
2
5
6
Đầu vào:
1 0
5
Đầu ra:
0
5
Đang tải editor...