Tải bản đầy đủ (.ppt) (95 trang)

TĂNG HIỆU QUẢ CHƯƠNG TRÌNH và PHONG CÁCH lập TRÌNH

Bạn đang xem bản rút gọn của tài liệu. Xem và tải ngay bản đầy đủ của tài liệu tại đây (529.63 KB, 95 trang )

TĂNG HIỆU QUẢ
CHƯƠNG TRÌNH
VÀ PHONG CÁCH
LẬP TRÌNH


Efficient Programs
 Trước hếế
t là giải thuật




Hãy dùng giải thuật hay nhấất có thể
Sau đó hãy nghĩ tới việc tăng tính hiệu quả của code
Ví dụ : Tính tổng của 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;

void main()
{
long n,m , sum ;
cout << ‘ vào n ‘ ; cin << n;
cout << ‘ vào m ‘ ; cin << m;
sum =(m + m+ n) * n / 2;
cout << ‘ Tổng = ‘ <
sum =0;


for(i = m ; i < = m+n; i++)

}

sum += i;
cout << ‘ Tổng = ‘ <}

2


Dùng chỉ thị chương trình dịch
 Một sốếcompilers có vai trò rấế
t lớn trong việc tốếi ưu

chương trình


Chúng phấn tích sấu mã nguốồn và làm mọi điêồu
“machinely” có thể



Ví dụ GNU g++ compiler trên Linux/Cygwin cho chương
trình viêất = c
 g++

–O5 –o myprog myprog.c
có thể cải thiện hiệu năng từ 10% đêấn 300%


3


Nhưng...
 Bạn vẫn có thể thực hiện những cải tiếế
n mà trình dịch

khống thể
 Bạn phải loại bỏ tấế
t cả những chỗ bấết hợp lý trong
code

Làm cho chương trình hiệu quả nhấất có thể
 Có thể phải xem lại khi thấế
y chương trình chạy chậm
 Vậy cấồ
n tập trung vào đấu để cải tiêấn nhanh nhấất, tốất
nhấấ
t?


4


Writing Efficient Code
 Xác định nguốồ
n gấy kém hiệu quả


Dư thừa tính toán - redundant computation




Chủ yêấu
 Trong

các procedure
 Các vòng lặp : Loops

5


Khởi tạo 1 lần, dùng nhiều lần
 Before

 After

float f()
{ double value = sin(0.25);
//
…..
}
double defaultValue = sin(0.25);
float f()
{ double value = defaultValue;
//
…..
6
}



Inline functions
 Nếế
u 1 hàm trong c++ chỉ gốồ
m những lệnh đơn

giản, khống co for, while .. Thì có thể khai
báo inline.





Inline code sẽ được chèn vào bấất cứ chỗ nào hàm
được goi.
Chương trình sẽ lớn hơn chút ít
Nhưng nhanh hơn , không dùng stack– 4 bước khi
1 hàm được gọi …

7


Inline functions
#include <iostream>
#include <cmath>
using namespace std;
inline double hypothenuse (double a, double b)
{
return sqrt (a * a + b * b);
}

int main () {
double k = 6, m = 9;
// 2 dòng sau thực hiện như nhau:
cout << hypothenuse (k, m) << endl;
cout << sqrt (k * k + m * m) << endl;
return 0;

}

8


Static Variables
 Kiểu dữ liệu Static tham chiếế
u tới global hay

'static' variables , chúng được cấếp phát bộ nhớ khi
dịch compile-time.
int int_array[100];
int main() {
static float float_array[100];
double double_array[100];
char *pchar;
pchar = (char *)malloc(100);
/* .... */
return (0);
}

9



Static Variables
 Các biếế
n khai báo trong CT con đ ược cấế
p phát b ộ nh ớ khi

ct con được gọi và sẽ bị loại bỏ khi kếết thúc ct con.
 Khi bạn gọi lại CT con, các biếế
n cục b ộ lại đ ược cấế
p phát
và khởi tạo lại.
 Nếế
u bạn muốến 1 giá trị vẫn được lưu lại cho đếến khi kếết
thúc toàn chương trình, bạn cấồn khai báo biếến cục bộ
của CT con đó là static và khởi tạo cho nó 1 giá tr ị.
 Việc khởi tạo sẽ chỉ thực hiện lấầ
n đàu tiên ch ương
trình được gọi và giá trị sau khi biêấ
n đ ổi s ẽ đ ược lưu
cho các lấần gọi sau.
 Băồ
ng cách này 1 ct con có thể “nhớ” một vài m ẩu tin sau m ỗi
lấồn được gọi.
 Dùng biếế
n Static thay vì Global :
 Cái hay của 1 biêấ
n static là nó là local của CT con, => tránh
được các side efects.

10



Stack, heap
 Khi thực hiện , vùng dữ liệu data segment của 1

chương trình được chia làm 3 phấồn :


- static, stack, và heap data.

 Static: global hay static variables
 Stack data:


- các biêấn cục bộ của ct con
-

ví dụ double_array trong ví dụ trên.

 Heap data:



- Dữ liệu được cấấp phát động (vd, pchar trong ví dụ trên).
- Dữ liệu này sẽ còn cho đêấn khi ta giải phóng hoặc khi kêất
thúc CT.

11



Macros


#define max(a,b) (a>b?a:b)
 Các hàm Inline cũng giốế
ng như macros vì cả 2 được khai triển khi

dịch compile time
 macros được khai triển bởi preprocessor, còn inline functions được truyêồ
n
bởi compiler.
 Tuy nhiến có nhiếồ
u điểm khác biệt:
 Inline functions tuấn thủ các th ủ tục nh ư 1 hàm binh th ường.
 Inline functions có cùng syntax như các hàm khác, ch ỉ có điêồ
u là có thêm t ừ
khóa inline khi khai báo hàm.
 Các biểu thức truyêồ
n như là đốấ
i sốấcho inline functions được tính 1 lấồn.
Trong 1 sốấtrường hợp, biểu thức truyêồn như tham sốấcho macros có th ể
được tính lại nhiêồu hơn 1 lấồn.
 Bạn khống thể gỡ rốấ
i cho macros, nhưng với inline functions thì có thể.

12


Tính toán trước các giá trị
 Nếế

u bạn phải tính đi tính lại 1 biểu thức, thì nến tính

trước 1 lấồn và lưu lại giá trị, rốồi dùng giá trị ấếy sau này

static int[] values =
int f(int i) {
{0, 0, 2,3*3-3, ..., 9*9-9};
if (i < 10 && i >= 0)
int
f(int
i)
{
{
if (i < 10 && i >= 0)
return i * i - i;
{
return
values[i];
}
}
return 0;
return
0;
}
}
13


Loại bỏ những biểu thức thông
thường

 Đừng tính cùng một biểu thức nhiếồ
u lấồn!
 Một sốếcompilers có thể nhận biếế
t và xử lý.

for (i = 1; i<=10;i++) x += strlen(str);
Y = 15 + strlen(str);
len = strlen(str);
for (i = 1;i<=10;i++) x += len;
Y = 15 + len;
14


Sử dụng các biến đổi số học!
 Trình dịch khống thể tự động xử lý

if (a > sqrt(b))
x = a*a + 3*a + 2;
if (a *a > b)
x = (a+1)*(a+2);
15


Dùng “lính canh” -Tránh những
kiểm tra không cần thiết
 Trước

char s[100], searchValue;
int pos,tim, size ;
….. Gán giá trị cho s, searchValue


size = strlen(s);
pos = 0;
while (pos < size) && (s[pos] != searchValue)
do pos++;
If (pos >= size) tim =0 else
tim = 1;
16


Dùng “lính canh” ….
 Ý tưởng chung


Đặt giá trị cấồn tìm vào cuốấi xấu



Luốn tìm thấấy !
Nhưng nêấu vị trí > size => khong tim thay !



size = strlen(s);
strcat(s, searchValue);
pos = 0;
while ( s[pos] != searchValue)
do pos++;
If (pos >= size) tim =0 else
tim = 1;


Có thể làm tương tự với mảng, danh sách …

17


Dịch chuyển những biểu thức bất
biến ra khỏi vòng lặp
 Đừng lặp các biểu thức tính toán khống cấồ
n thiếết
 Một sốếCompilers có thể tự xử lý!

for (i =0; i<100;i++)
plot(i, i*sin(d));

M = sin(d);
for (i =0; i<100;i++)
plot(i, i*M);
18


Không dùng các vòng lặp ngắn
for (i =j; i<= j+3;i++)
sum += q*i -i*7;

i = j;
sum += q*i -i*7;
i ++;
sum += q*i -i*7;
i ++;

sum += q*i-i*7;
19


Giảm thời gian tính toán
 Trong mố phỏng

Neural Network
người ta thường
dùng hàm có tến
sigmoid
 Với X dương lớn ta
có sigmoid(x) ≅ 1
 Với x ấm “lớn”
sigmoid (x) ≅ 0

1
sigmoid ( x) =
1 + e − kx

20


Tính Sigmoid
float sigmoid (float x )
{
return 1.0 / (1.0 + exp(-x))
};

21



Tính Sigmoid
 Hàm exp(-x) mấế
t rấết nhiếồ
u thời gian để tính!


Những hàm kiểu này người ta phải dùng khai triển chuỗi
 Chuỗi Taylor /Maclaurin
 Tính tổng các sốấhạng dạng ((-x)n / n!)
 Mỗi sốấhạng lại dùng các phép toán v ới sốấchấấ
m động

 Nói chung các mố phỏng neural network gọi

hàm này trăm triệu lấồn trong mỗi lấồn thực
hiện.
 Chính vì vậy , sigmoid(x) chiếế
m phấồn lớn thời
gian (khoảng 70-80%)
22


Tính Sigmoid – Giải pháp
 Thay vì tính hàm mọi lúc


Tính hàm tại N điểm và xấy dựng 1 mảng.




Trong mỗi lấồn gọi sigmoid

x0 sigmoid(x0)
x1 sigmoid(x0)
x2 sigmoid(x0)

giá trị gấồ
n nhấất của x và kêấ
t quả ứng
với giá trị ấấy
 Thực hiện nội suy tuyêấ
n tính - linear
interpolation
 Tìm

x3 sigmoid(x0)
x4 sigmoid(x0)
x5 sigmoid(x0)
x6 sigmoid(x0)
.
.
.
x99 sigmoid(x99)

23


Tính Sigmoid

if (x x0 sigmoid(x0)
x1 sigmoid(x0)
x2 sigmoid(x0)
x3 sigmoid(x0)
x4 sigmoid(x0)
x5 sigmoid(x0)
x6 sigmoid(x0)
.
.
.
x99 sigmoid(x99)

if (x > x99) return (1.0);

24


Tính Sigmoid
 Chọn sốếcác điểm (N = 1000, 10000, v.v.) tùy theo độ

chính xác mà bạn muốến

Tốấn kêấm thêm khống gian bọ nhớ cho mỗi điểm là 2 float
hay double tức là 8 – 16 bytes/ điểm
 Khởi tạo giá trị cho mảng khi băế
t đấồu thực hiện


25



×