Memang saya tidak mengerti. Katakanlah Anda memiliki memori dengan kata memori yang panjangnya 1 byte. Mengapa Anda tidak dapat mengakses variabel panjang 4 byte dalam akses memori tunggal pada alamat yang tidak selaras (yaitu tidak dapat dibagi dengan 4), karena ini adalah kasus dengan alamat yang disejajarkan?
195
Jawaban:
Ini adalah batasan dari banyak prosesor yang mendasarinya. Biasanya dapat dikerjakan dengan melakukan 4 pengambilan byte yang tidak efisien daripada mengambil kata yang efisien, tetapi banyak penspesifikasi bahasa memutuskan akan lebih mudah hanya untuk melarang mereka dan memaksa segala sesuatu untuk disejajarkan.
Ada lebih banyak informasi dalam tautan ini yang ditemukan OP.
sumber
Subsistem memori pada prosesor modern dibatasi untuk mengakses memori pada rincian dan keselarasan ukuran kata-katanya; hal ini terjadi karena sejumlah alasan.
Mempercepat
Prosesor modern memiliki beberapa tingkat memori cache yang harus ditarik data; mendukung pembacaan byte tunggal akan membuat throughput subsistem memori terikat erat dengan throughput unit eksekusi (alias cpu-terikat); ini semua mengingatkan bagaimana mode PIO dilampaui oleh DMA karena banyak alasan yang sama pada hard drive.
CPU selalu membaca pada ukuran kata (4 byte pada prosesor 32-bit), jadi ketika Anda melakukan akses alamat yang tidak selaras - pada prosesor yang mendukungnya - prosesor akan membaca beberapa kata. CPU akan membaca setiap kata dari memori yang dialamatkan oleh alamat yang Anda minta. Ini menyebabkan amplifikasi hingga 2X jumlah transaksi memori yang diperlukan untuk mengakses data yang diminta.
Karena itu, dapat dengan mudah menjadi lebih lambat untuk membaca dua byte daripada empat. Misalnya, Anda memiliki struct dalam memori yang terlihat seperti ini:
Pada prosesor 32-bit kemungkinan besar akan diselaraskan seperti yang ditunjukkan di sini:
Prosesor dapat membaca masing-masing anggota ini dalam satu transaksi.
Katakanlah Anda memiliki versi struct yang dikemas, mungkin dari jaringan di mana ia dikemas untuk efisiensi transmisi; mungkin terlihat seperti ini:
Membaca byte pertama akan sama.
Ketika Anda meminta prosesor untuk memberi Anda 16 bit dari 0x0005 itu harus membaca kata dari dari 0x0004 dan bergeser ke kiri 1 byte untuk menempatkannya dalam register 16-bit; beberapa pekerjaan tambahan, tetapi sebagian besar dapat mengatasinya dalam satu siklus.
Ketika Anda meminta 32 bit dari 0x0001 Anda akan mendapatkan amplifikasi 2X. Prosesor akan membaca dari 0x0000 ke dalam register hasil dan bergeser ke kiri 1 byte, kemudian membaca lagi dari 0x0004 ke dalam register sementara, menggeser ke kanan 3 byte, kemudian
OR
dengan register hasil.Jarak
Untuk setiap ruang alamat yang diberikan, jika arsitektur dapat mengasumsikan bahwa 2 LSB selalu 0 (misalnya, mesin 32-bit) maka ia dapat mengakses memori 4 kali lebih banyak (2 bit yang disimpan dapat mewakili 4 keadaan berbeda), atau jumlah yang sama memori dengan 2 bit untuk sesuatu seperti bendera. Melepaskan 2 LSB dari suatu alamat akan memberi Anda keselarasan 4-byte; juga disebut sebagai langkah 4 byte. Setiap kali sebuah alamat bertambah maka secara efektif menambah bit 2, bukan bit 0, yaitu, 2 bit terakhir akan selalu terus menjadi
00
.Ini bahkan dapat mempengaruhi desain fisik sistem. Jika bus alamat membutuhkan 2 bit lebih sedikit, mungkin ada 2 pin lebih sedikit pada CPU, dan 2 jejak lebih sedikit pada papan sirkuit.
Atomicity
CPU dapat beroperasi pada kata memori yang selaras secara atom, artinya tidak ada instruksi lain yang dapat mengganggu operasi itu. Ini sangat penting untuk operasi yang benar dari banyak struktur data bebas kunci dan paradigma konkurensi lainnya .
Kesimpulan
Sistem memori prosesor agak sedikit lebih kompleks dan terlibat daripada yang dijelaskan di sini; diskusi tentang bagaimana prosesor x86 sebenarnya menangani memori dapat membantu (banyak prosesor bekerja dengan cara yang sama).
Ada banyak manfaat lainnya untuk mematuhi penyelarasan memori yang dapat Anda baca di artikel IBM ini .
Penggunaan utama komputer adalah mengubah data. Arsitektur dan teknologi memori modern telah dioptimalkan selama beberapa dekade untuk memfasilitasi mendapatkan lebih banyak data, masuk, keluar, dan antara unit eksekusi lebih banyak dan lebih cepat - dengan cara yang sangat andal.
Bonus: Tembolok
Penyelarasan-untuk-kinerja lain yang saya singgung sebelumnya adalah penyelarasan pada garis cache yang (misalnya, pada beberapa CPU) 64B.
Untuk info lebih lanjut tentang berapa banyak kinerja yang bisa diperoleh dengan memanfaatkan cache, lihat Galeri Efek Cache Prosesor ; dari pertanyaan ini tentang ukuran cache-line
sumber
Anda dapat menggunakan beberapa prosesor ( nehalem dapat melakukan ini ), tetapi sebelumnya semua akses memori diselaraskan pada jalur 64-bit (atau 32-bit), karena bus berukuran 64 bit, Anda harus mengambil 64 bit sekaligus , dan secara signifikan lebih mudah untuk mengambil ini dalam 'potongan' selaras dari 64 bit.
Jadi, jika Anda ingin mendapatkan satu byte, Anda mengambil potongan 64-bit dan kemudian menutupi bit yang tidak Anda inginkan. Mudah dan cepat jika byte Anda berada di ujung kanan, tetapi jika itu di tengah-tengah potongan 64-bit, Anda harus menutupi bit yang tidak diinginkan dan kemudian menggeser data ke tempat yang tepat. Lebih buruk lagi, jika Anda menginginkan variabel 2 byte, tetapi itu terbagi menjadi 2 chunks, maka itu diperlukan dua kali lipat dari akses memori yang diperlukan.
Jadi, karena semua orang menganggap memori itu murah, mereka hanya membuat kompilator menyelaraskan data pada ukuran chunk prosesor sehingga kode Anda berjalan lebih cepat dan lebih efisien dengan biaya memori yang terbuang.
sumber
Pada dasarnya, alasannya adalah karena bus memori memiliki panjang tertentu yang jauh, jauh lebih kecil dari ukuran memori.
Jadi, CPU membaca dari cache L1 on-chip, yang sering 32KB hari ini. Tetapi bus memori yang menghubungkan cache L1 ke CPU akan memiliki ukuran garis cache yang jauh lebih kecil. Ini akan berada di urutan 128 bit .
Begitu:
Akses yang tidak selaras kadang-kadang akan tumpang tindih dua garis cache, dan ini akan membutuhkan cache yang sepenuhnya baru dibaca untuk mendapatkan data. Bahkan mungkin ketinggalan semua jalan keluar ke DRAM.
Selain itu, beberapa bagian dari CPU harus berdiri di atas kepalanya untuk menyatukan satu objek dari dua garis cache yang berbeda yang masing-masing memiliki data. Pada satu baris, itu akan berada dalam bit urutan sangat tinggi, di lain, bit urutan sangat rendah.
Akan ada perangkat keras khusus yang terintegrasi penuh ke dalam pipeline yang menangani memindahkan objek yang diluruskan ke bit yang diperlukan dari bus data CPU, tetapi perangkat keras tersebut mungkin kurang untuk objek yang tidak selaras, karena mungkin lebih masuk akal untuk menggunakan transistor tersebut untuk mempercepat dioptimalkan dengan benar program.
Dalam kasus apa pun, pembacaan memori kedua yang kadang-kadang diperlukan akan memperlambat pipa terlepas dari seberapa banyak perangkat keras tujuan khusus (secara hipotetis dan bodoh) yang didedikasikan untuk memperbaiki operasi memori yang tidak selaras.
sumber
@ joshperry telah memberikan jawaban yang sangat baik untuk pertanyaan ini. Selain jawabannya, saya memiliki beberapa angka yang menunjukkan secara grafis efek yang dijelaskan, terutama amplifikasi 2X. Berikut ini tautan ke spreadsheet Google yang menunjukkan seperti apa efek dari perataan kata. Selain itu, inilah tautan ke inti Github dengan kode untuk pengujian. Kode tes diadaptasi dari artikel yang ditulis oleh Jonathan Rentzsch yang dirujuk oleh @joshperry. Pengujian dijalankan pada Macbook Pro dengan prosesor quad-core 2,8 GHz Intel Core i7 64-bit dan RAM 16GB.
sumber
x
dany
koordinat artinya?Jika sebuah sistem dengan memori byte-addressable memiliki bus memori 32-bit-lebar, itu berarti ada efektif sistem memori empat-byte yang semuanya kabel untuk membaca atau menulis alamat yang sama. Pembacaan 32-bit yang selaras akan membutuhkan informasi yang disimpan dalam alamat yang sama di keempat sistem memori, sehingga semua sistem dapat menyediakan data secara bersamaan. Pembacaan 32-bit yang tidak selaras akan memerlukan beberapa sistem memori untuk mengembalikan data dari satu alamat, dan beberapa untuk mengembalikan data dari alamat yang lebih tinggi berikutnya. Meskipun ada beberapa sistem memori yang dioptimalkan untuk dapat memenuhi permintaan tersebut (selain alamatnya, mereka secara efektif memiliki sinyal "plus satu" yang menyebabkan mereka menggunakan alamat yang lebih tinggi dari yang ditentukan) fitur semacam itu menambah biaya yang cukup besar dan kompleksitas sistem memori;
sumber
Jika Anda memiliki bus data 32bit, jalur alamat bus alamat yang terhubung ke memori akan mulai dari A 2 , sehingga hanya alamat sejajar 32bit yang dapat diakses dalam siklus bus tunggal.
Jadi, jika sebuah kata merentang batas penyejajaran alamat - yaitu A 0 untuk data 16/32 bit atau A 1 untuk data 32 bit bukan nol, dua siklus bus diperlukan untuk mendapatkan data.
Beberapa arsitektur / set instruksi tidak mendukung akses yang tidak selaras dan akan menghasilkan pengecualian pada upaya-upaya tersebut, sehingga kompiler yang dihasilkan kode akses yang tidak selaras tidak hanya memerlukan siklus bus tambahan, tetapi juga instruksi tambahan, membuatnya bahkan lebih efisien.
sumber
Pada PowerPC Anda dapat memuat integer dari alamat ganjil tanpa masalah.
Sparc dan I86 dan (saya pikir) Itatnium meningkatkan pengecualian perangkat keras ketika Anda mencoba ini.
Satu beban 32 bit vs empat beban 8 bit tidak akan membuat banyak perbedaan pada kebanyakan prosesor modern. Apakah data sudah dalam cache atau tidak akan memiliki efek yang jauh lebih besar.
sumber