▫ Nếu số case trong câu lệnh switch nằm trong phạm vi hẹp, trình dịch sẽ biến đổi thành if – else if lồng nhau, và tạo thành 1 bảng các chỉ số, như vậy thao tác sẽ nhanh hơn.. Tối ưu m[r]
(1)Bài 7
(2)Nội dung
1. Tổng quan
2. Các nguyên lý bản
3. Một số kỹ thuật tăng hiệu chương trình
4. Tinh chỉnh mã nguồn
(3)1.
Tổng quan
(4)Làm để
tăng hiệu chương trình
▪ Giải thuật
▫ Dùng giải thuật tốt có thể
▫ Sau nghĩ tới việc tăng tính hiệu code
▫ Ví dụ: Tính tổng n số tự nhiên kể từ m void main() {
long n,m,i, sum ;
cout << ‘ vào n ‘ ; cin << n; cout << ‘ vào m ‘ ; cin << m; sum =0;
for(i = m ; i < m+n; i++) sum += i; cout << ‘ Tổng = ‘ <<sum;
}
void main() {
long n,m ;
cout << ‘ vào n ‘ ; cin << n; cout << ‘ vào m ‘ ; cin << m; cout << ‘ Tổng = ‘
(5)Dùng chỉ thị
chương trình dịch
▪ Một số compilers có khả tối ưu chương trình
▫ Phân tích sâu mã nguồn tự động tối ưu hóa
▫ Ví dụ GNU g++ compiler Linux/Cygwin cho chương trình viết C
g++ –O5 –o myprog myprog.c
(6)Tự
tối ưu hóa
▪ Tự thực cải tiến mà trình dịch khơng thể ▪ Loại bỏ tất chỗ bất hợp lý code
▫ Làm cho chương trình hiệu có thể
▪ Có thể phải xem lại thấy chương trình chạy chậm
▫ Cần tập trung vào đâu để cải tiến nhanh nhất, tốt nhất?
▪ Xác định nguồn gây hiệu quả
▫ Dư thừa tính tốn - redundant computation
▫ Chủ yếu
▸Trong hàm
(7)2.
Các nguyên tắc bản
(8)Quy tắc
cơ bản
▪ Đơn giản hóa Code - Code Simplification
▪ Đơn giản hóa vấn đề - Problem Simplification
▪ Không ngừng nghi ngờ - Relentless Suspicion
(9)Quy tắc
tăng tốc độ
Caching
▫Dữ liệu thường dùng cần phải dễ tiếp cận nhất, ln hữu
Lazy Evaluation
▫Khơng tính phần tử cho đến cần để
(10)Quy tắc
tăng tốc độ
▪ Có thể tăng tốc độ cách sử dụng thêm nhớ (mảng) ▪ Dùng thêm liệu có cấu trúc:
▫ Thời gian cho phép tốn thơng dụng giảm cách sử dụng thêm cấu trúc liệu với liệu bổ xung hoặc bằng cách thay đổi liệu cấu trúc cho dễ tiếp cận hơn
▪ Lưu kết tính trước:
(11)Quy tắc lặp
Loop rules
▪ Những điểm nóng - Hot spots phần lớn chương trình đến từ vịng lặp:
▪ Đưa Code khỏi vòng lặp:
▫ Thay thực việc tính tốn lần lặp, tốt thực hiện lần bên ngồi vịng lặp (nếu được)
▪ Kết hợp vòng lặp – loop fusion:
(12)Quy tắc lặp
Loop rules
▪ Kết hợp phép thử - Combining Tests:
▫ Trong vịng lặp kiểm tra tốt tốt phép thử LTV phải thay đổi điều kiện kết thúc vịng lặp “Lính gác” hay “Vệ sĩ” ví dụ cho quy tắc này.
▪ Loại bỏ Loop :
(13)Quy tắc hàm
Procedure Rules
▪ Khai báo hàm ngắn đơn giản (thường dòng) là inline
▫ Tránh phải thực bước hàm gọi,
(14)Tối ưu mã
C/C++
▪ Đặt kích thước mảng = 2n
▫ Với mảng, tạo số, trình dịch thực phép nhân, vậy, đặt kích thước mảng 2n để phép nhân
chuyển thành phép tốn dịch chuyển nhanh chóng
▪ Đặt case phạm vi hẹp
(15)Tối ưu mã
C/C++
▪ Đặt trường hợp thường gặp lệnh switch lên đầu
▫ Khi số trường hợp tuyển chọn nhiều tách biệt, trình dịch biến lệnh switch thành nhóm if – else if lồng Nếu bố trí case thường gặp lên trên, việc thực nhanh
▪ Tái tạo switch lớn thành switches lồng nhau
▫ Khi số cases nhiều, chủ động chia chúng thành switch lồng nhau, nhóm gồm case thường gặp, nhóm gồm những case gặp=> kết phép thử hơn, tốc độ
(16)Ví dụ case 0: letter = ‘D'; break;
case 1: letter = ‘H'; break;
case 2: letter = ‘B'; break;
case 3: letter = ‘K'; break;
}
// Hoặc là:
if (queue == 0) letter = ‘D';
else if (queue == 1) letter = ‘H';
else if (queue == 2) letter = ‘B';
else letter = ‘K';
(17)Tối ưu mã
C/C++
▪ Minimize local variables
▫ Các biến cục cấp phát khởi tạo hàm gọi, giải phóng hàm kết thúc, thời gian
▪ Khai báo biến cục phạm vi nhỏ nhất ▪ Hạn chế số tham số hàm
(18)Tối ưu mã
C/C++
▪ Đừng định nghĩa giá trị trả về, không sử dụng void
▪ Lưu ý vị trí tham chiếu tới code data
▫ Các liệu code lưu nhớ cache để tham khảo sau (nếu được) Việc tham khảo từ nhớ cache sẽ
(19)Tối ưu mã
C/C++
▪ Nên dùng int thay char hay short (mất thời gian convert), biết int không âm, dùng unsigned int
▪ Hãy định nghĩa hàm khởi tạo đơn giản ▪ Thay gán, khởi tạo giá trị cho biến
▪ Hãy dùng danh sách khởi tạo hàm khởi tạo
Employee::Employee(String name, String designation) { m_name = name;
m_designation = designation; }
/* === Optimized Version === */
Employee::Employee(String name, String designation): m_name(name), m_destignation (designation) { }
▪ Đừng định nghĩa hàm ảo tùy hứng: "just in case" virtual functions
(20)Sử dụng
bộ nhớ và con trỏ
▪ Con trỏ (pointer) gọi “niềm tự hào” C/C++, nhiên thực tế nguyên nhân làm đau đầu cho LTV, hầu hết trường hợp sụp đổ hệ thống, hết nhớ, vi phạm vùng nhớ… xuất phát từ việc sử dụng trỏ không hợp lý