Các ngôn ngữ có bộ tính năng tương tự. Sự khác biệt về hiệu suất xuất phát từ việc Fortran nói rằng răng cưa không được phép, trừ khi sử dụng câu lệnh THIẾT BỊ. Bất kỳ mã nào có bí danh đều không hợp lệ, Fortran, nhưng tùy thuộc vào người lập trình và không phải là trình biên dịch để phát hiện các lỗi này. Do đó, trình biên dịch Fortran bỏ qua các bí danh có thể có của con trỏ bộ nhớ và cho phép chúng tạo mã hiệu quả hơn. Hãy xem ví dụ nhỏ này trong C:
void transform (float *output, float const * input, float const * matrix, int *n)
{
int i;
for (i=0; i<*n; i++)
{
float x = input[i*2+0];
float y = input[i*2+1];
output[i*2+0] = matrix[0] * x + matrix[1] * y;
output[i*2+1] = matrix[2] * x + matrix[3] * y;
}
}
Chức năng này sẽ chạy chậm hơn so với đối tác Fortran sau khi tối ưu hóa. Tại sao như vậy? Nếu bạn viết các giá trị vào mảng đầu ra, bạn có thể thay đổi các giá trị của ma trận. Rốt cuộc, các con trỏ có thể chồng lên nhau và trỏ đến cùng một đoạn bộ nhớ (bao gồm cả int
con trỏ!). Trình biên dịch C buộc phải tải lại bốn giá trị ma trận từ bộ nhớ cho tất cả các tính toán.
Trong Fortran trình biên dịch có thể tải các giá trị ma trận một lần và lưu trữ chúng trong các thanh ghi. Nó có thể làm như vậy bởi vì trình biên dịch Fortran giả định các con trỏ / mảng không trùng nhau trong bộ nhớ.
May mắn thay, restrict
từ khóa và răng cưa nghiêm ngặt đã được đưa vào tiêu chuẩn C99 để giải quyết vấn đề này. Nó cũng được hỗ trợ trong hầu hết các trình biên dịch C ++. Từ khóa cho phép bạn cung cấp cho trình biên dịch một gợi ý rằng lập trình viên hứa rằng một con trỏ không bí danh với bất kỳ con trỏ nào khác. Bí danh nghiêm ngặt có nghĩa là lập trình viên hứa rằng các con trỏ thuộc loại khác nhau sẽ không bao giờ trùng nhau, ví dụ như double*
sẽ không trùng lặp với một int*
(với ngoại lệ cụ thể char*
và void*
có thể trùng lặp với bất cứ điều gì).
Nếu bạn sử dụng chúng, bạn sẽ nhận được cùng tốc độ từ C và Fortran. Tuy nhiên, khả năng chỉ sử dụng restrict
từ khóa với các chức năng quan trọng về hiệu suất có nghĩa là các chương trình C (và C ++) an toàn hơn và dễ viết hơn. Ví dụ, hãy xem xét mã Fortran không hợp lệ : CALL TRANSFORM(A(1, 30), A(2, 31), A(3, 32), 30)
, mà hầu hết các trình biên dịch Fortran sẽ vui vẻ biên dịch mà không có bất kỳ cảnh báo nào nhưng đưa ra một lỗi chỉ xuất hiện trên một số trình biên dịch, trên một số phần cứng và với một số tùy chọn tối ưu hóa.