2012-06-06 31 views
10

Tôi tự hỏi có nên sử dụng int (32 bit trên cả x86 và x86_64) trên các chương trình 64 bit cho các biến không có gì đặc biệt và không thực sự cần đến 2^64, như các bộ đếm lặp hoặc nếu tốt hơn nên sử dụng size_t khớp với kích thước từ của CPU.Bất kỳ lý do nào để sử dụng các số nguyên 32 bit cho các hoạt động chung trên CPU 64 bit?

Để chắc chắn nếu bạn tiếp tục sử dụng int bạn tiết kiệm một nửa bộ nhớ, và điều đó có nghĩa là nói về bộ nhớ CPU, 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 trước khi sử dụng.

EDIT: Tôi đã chạy một số thử nghiệm với một chương trình của tôi (xem self answer, tôi vẫn giữ janneb như được chấp nhận mặc dù vì nó là tốt). Nó chỉ ra rằng có một cải tiến hiệu suất đáng kể.

+1

Bộ đếm lặp không nên ở trong bộ nhớ cache CPU; họ nên cư trú trong sổ đăng ký. –

+0

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

+0

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ụ. –

Trả lời

4

Đố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ơ!

3

Về mặt bộ nhớ cache, nó sẽ tiết kiệm không gian; cache xử lý các khối dữ liệu, bất kể CPU đã yêu cầu một địa chỉ duy nhất hay đoạn hoàn chỉnh bằng kích thước khối bộ nhớ cache. Vì vậy, nếu bạn đang hỏi liệu các số 32 bit có 64-bit không gian bên trong bộ nhớ cache trên các máy 64 bit thì câu trả lời là không, chúng sẽ vẫn lấy 32 bit cho chính chúng. Vì vậy, nói chung, nó sẽ giúp bạn tiết kiệm một số không gian, đặc biệt là nếu bạn đang sử dụng mảng lớn với thường xuyên truy cập, vv

Theo ý kiến ​​cá nhân của tôi, một đơn giản int trông đơn giản hơn size_t và hầu hết các biên tập viên sẽ không nhận ra size_t loại để làm nổi bật cú pháp cũng sẽ tốt hơn nếu bạn sử dụng int. ;)

+1

Tôi khuyên bạn nên ngừng sử dụng bất kỳ trình chỉnh sửa nào không nhận ra 'size_t' ngay lập tức! – Shahbaz

+2

Chắc chắn ngừng sử dụng trình chỉnh sửa không cho phép bạn định cấu hình nội dung được đánh dấu là :-) –

+0

trên cửa sổ, nhiều trình chỉnh sửa (MS Visual Studio, siêu chỉnh sửa, notepad ++, editplus) không nhận dạng size_t. nếu một trong những phát triển trên môi trường Unix/Linux sau đó an toàn của nó, nếu không, cũng vẫn an toàn chỉ là một chút sai lầm hơn: P anyways, đây không phải là điểm chính .. :) – xenodevil

0

Đây phải là quyết định của nhà phát triển trình biên dịch.

int là loại tự nhiên cho số nguyên được ký "bình thường". Nó tùy thuộc vào trình biên dịch để quyết định nó là gì.
Nếu, trên một nền tảng cụ thể, có một lợi thế thực sự khi sử dụng số nguyên 64 bit, nhà phát triển trình biên dịch dự kiến ​​sẽ thực hiện int 64 bit. Tiêu chuẩn cho phép nó.

Nếu nhà phát triển trình biên dịch quyết định gắn bó với số nguyên 32 bit, bạn thường nên tin tưởng anh ta.
Có thể, trong một số trường hợp hiếm hoi, sau một nỗ lực tối ưu hóa đáng kể, bạn sẽ thấy rằng long hoạt động tốt hơn. Sau đó, bạn có thể muốn thay đổi.

3

Tôi đang mã hóa một chút hard spheres model. Nguồn có thể được tìm thấy trên github.

Tôi đã cố gắng tiếp tục sử dụng size_t cho các biến được sử dụng làm chỉ mục mảng và int nơi tôi thực hiện các thao tác khác, không liên quan đến kích thước từ. Cải thiện hiệu suất là đáng kể: giảm thời gian thực hiện từ 27 đến ~ 24.

+0

ví dụ thực tế rất tốt mà chứng minh vấn đề trong nơi đầu tiên. +1 – hroptatyr

Các vấn đề liên quan