Đối với chỉ số mảng và số học con trỏ, các loại có cùng kích thước với con trỏ (thường là size_t và ptrdiff_t) có thể tốt hơn vì chúng không cần số 0 hoặc dấu mở rộng thanh ghi. Cân nhắc
float onei(float *a, int n)
{
return a[n];
}
float oneu(float *a, unsigned n)
{
return a[n];
}
float onep(float *a, ptrdiff_t n)
{
return a[n];
}
float ones(float *a, size_t n)
{
return a[n];
}
Với GCC 4.4 -O2 trên x86_64 asm sau đây được tạo:
.p2align 4,,15
.globl onei
.type onei, @function
onei:
.LFB3:
.cfi_startproc
movslq %esi,%rsi
movss (%rdi,%rsi,4), %xmm0
ret
.cfi_endproc
.LFE3:
.size onei, .-onei
.p2align 4,,15
.globl oneu
.type oneu, @function
oneu:
.LFB4:
.cfi_startproc
mov %esi, %esi
movss (%rdi,%rsi,4), %xmm0
ret
.cfi_endproc
.LFE4:
.size oneu, .-oneu
.p2align 4,,15
.globl onep
.type onep, @function
onep:
.LFB5:
.cfi_startproc
movss (%rdi,%rsi,4), %xmm0
ret
.cfi_endproc
.LFE5:
.size onep, .-onep
.p2align 4,,15
.globl ones
.type ones, @function
ones:
.LFB6:
.cfi_startproc
movss (%rdi,%rsi,4), %xmm0
ret
.cfi_endproc
.LFE6:
.size ones, .-ones
Như có thể thấy, các phiên bản với int và chỉ số int unsigned (onei và oneu) đòi hỏi thêm lệnh (movslq/mov) để ký/không mở rộng thanh ghi.
Như đã đề cập trong nhận xét, nhược điểm là mã hóa thanh ghi 64 bit chiếm nhiều không gian hơn phần 32 bit, làm tăng kích thước mã. Thứ hai, các biến ptrdiff_t/size_t cần nhiều bộ nhớ hơn int tương đương; nếu bạn có các mảng như vậy, nó chắc chắn có thể ảnh hưởng đến hiệu năng nhiều hơn lợi ích tương đối nhỏ của việc tránh phần mở rộng số không/dấu. Nếu không chắc chắn, hồ sơ!
Bộ đếm lặp không nên ở trong bộ nhớ cache CPU; họ nên cư trú trong sổ đăng ký. –
1. Tôi tin rằng các trình biên dịch tự động sửa nhiều thứ như vậy cho bạn. 2. Tại sao bạn không viết một chương trình kiểm tra hiệu suất giữa hai? – Shahbaz
chắc chắn, nhưng "nhưng tôi không biết sau đó nếu trên máy 64 bit mỗi số 32 bit phải được mở rộng đến 64 bit trước khi sử dụng bất kỳ". Và đó chỉ là một ví dụ. –