Pertama-tama akses memori utama sangat mahal. Saat ini CPU 2GHz (paling lambat sekali) memiliki kutu 2G (siklus) per detik. CPU (virtual core saat ini) dapat mengambil nilai dari registernya sekali per centang. Karena inti virtual terdiri dari beberapa unit pemrosesan (ALU - unit logika aritmatika, FPU dll), maka sebenarnya dapat memproses instruksi tertentu secara paralel jika memungkinkan.
Akses memori utama berharga sekitar 70ns hingga 100ns (DDR4 sedikit lebih cepat). Kali ini pada dasarnya mencari cache L1, L2 dan L3 dan kemudian mengenai memori (kirim perintah ke pengontrol memori, yang mengirimkannya ke bank memori), tunggu tanggapannya dan selesai.
100ns berarti sekitar 200 ticks. Jadi pada dasarnya jika sebuah program akan selalu melewatkan cache yang diakses oleh setiap memori, CPU akan menghabiskan sekitar 99,5% dari waktunya (jika hanya membaca memori) menganggur menunggu memori.
Untuk mempercepat, ada cache L1, L2, L3. Mereka menggunakan memori yang langsung ditempatkan pada chip dan menggunakan berbagai jenis rangkaian transistor untuk menyimpan bit yang diberikan. Ini membutuhkan lebih banyak ruang, lebih banyak energi dan lebih mahal daripada memori utama karena CPU biasanya diproduksi menggunakan teknologi yang lebih maju dan kegagalan produksi dalam memori L1, L2, L3 memiliki kesempatan untuk membuat CPU tidak berharga (cacat) sehingga cache L1, L2, L3 yang besar meningkatkan tingkat kesalahan yang menurunkan hasil yang secara langsung menurunkan ROI. Jadi ada trade off besar ketika datang ke ukuran cache yang tersedia.
(saat ini seseorang menciptakan lebih banyak cache L1, L2, L3 untuk dapat menonaktifkan bagian-bagian tertentu untuk mengurangi kemungkinan cacat produksi yang sebenarnya adalah area memori cache membuat kerusakan CPU membuat kerusakan CPU secara keseluruhan).
Untuk memberikan ide pengaturan waktu (sumber: biaya untuk mengakses cache dan memori )
- L1 cache: 1ns hingga 2ns (2-4 siklus)
- L2 cache: 3ns hingga 5ns (6-10 cycle)
- L3 cache: 12ns hingga 20ns (24-40 siklus)
- RAM: 60ns (120 siklus)
Karena kami mencampur jenis CPU yang berbeda, ini hanya perkiraan tetapi memberikan ide bagus apa yang sebenarnya terjadi ketika nilai memori diambil dan kami mungkin memiliki hit atau miss di lapisan cache tertentu.
Jadi cache pada dasarnya mempercepat akses memori (60ns vs 1ns).
Mengambil nilai, menyimpannya dalam cache untuk kesempatan membaca ulang itu baik untuk variabel yang sering diakses tetapi untuk operasi salinan memori masih lambat karena seseorang hanya membaca nilai, menulis nilai di suatu tempat, dan tidak pernah membaca nilai. lagi ... tidak ada cache hit, mati lambat (di samping ini dapat terjadi secara paralel karena kita memiliki eksekusi yang tidak sesuai pesanan).
Salinan memori ini sangat penting sehingga ada berbagai cara untuk mempercepatnya. Pada masa-masa awal, memori sering dapat menyalin memori di luar CPU. Itu ditangani oleh pengontrol memori secara langsung, sehingga operasi penyalinan memori tidak mencemari cache.
Tetapi selain dari salinan memori biasa, akses serial lainnya terhadap memori juga cukup umum. Contohnya adalah menganalisis serangkaian informasi. Memiliki array bilangan bulat dan menghitung jumlah, rata-rata, rata-rata, atau bahkan lebih sederhana, menemukan nilai tertentu (filter / pencarian) adalah kelas algoritma yang sangat penting yang dijalankan setiap saat pada CPU tujuan umum.
Jadi dengan menganalisis pola akses memori, jelas bahwa data dibaca berurutan sangat sering. Ada probabilitas tinggi bahwa jika suatu program membaca nilai pada indeks i, maka program tersebut juga akan membaca nilai i +1. Probabilitas ini sedikit lebih tinggi daripada probabilitas bahwa program yang sama juga akan membaca nilai i + 2 dan seterusnya.
Jadi diberi alamat memori itu (dan masih) adalah ide yang bagus untuk membaca dan mengambil nilai tambahan. Ini adalah alasan mengapa ada mode boost.
Akses memori dalam mode boost berarti, bahwa suatu alamat dikirimkan dan beberapa nilai dikirimkan secara berurutan. Setiap pengiriman nilai tambahan hanya membutuhkan sekitar 10ns tambahan (atau bahkan di bawah).
Masalah lain adalah alamat. Mengirim alamat membutuhkan waktu. Untuk menangani sebagian besar memori, alamat besar harus dikirim. Pada hari-hari awal itu berarti bahwa bus alamat tidak cukup besar untuk mengirim alamat dalam satu siklus (centang) dan lebih dari satu siklus diperlukan untuk mengirim alamat menambahkan lebih banyak penundaan.
Misalnya, cache line 64 byte berarti memori dibagi dalam blok memori yang berbeda (tidak tumpang tindih) yang berukuran 64bytes. 64bytes berarti alamat awal setiap blok memiliki enam bit alamat terendah yang selalu nol. Jadi mengirim enam bit nol ini setiap kali tidak diperlukan meningkatkan ruang alamat 64 kali untuk sejumlah lebar bus alamat (efek selamat datang).
Masalah lain yang dipecahkan oleh baris cache (di samping membaca di depan dan menyimpan / membebaskan enam bit pada bus alamat) adalah cara mengatur cache. Sebagai contoh jika cache akan dibagi dalam 8 byte (64bit) blok (sel) seseorang perlu menyimpan alamat sel memori sel cache ini menyimpan nilai untuk bersama dengannya. Jika alamatnya juga 64bit, ini berarti bahwa setengah ukuran cache dikonsumsi oleh alamat yang menghasilkan overhead 100%.
Karena garis cache adalah 64bytes dan CPU mungkin menggunakan 64bit - 6bit = 58bit (tidak perlu menyimpan bit nol terlalu kanan) berarti kita dapat melakukan cache 64bytes atau 512bits dengan overhead 58bit (overhead 11%). Pada kenyataannya alamat yang disimpan bahkan lebih kecil dari ini tetapi ada informasi status (seperti apakah garis cache valid dan akurat, kotor dan perlu ditulis kembali dalam ram dll).
Aspek lain adalah bahwa kita memiliki cache set-asosiatif. Tidak setiap sel cache dapat menyimpan alamat tertentu tetapi hanya sebagian dari mereka. Ini membuat bit alamat tersimpan yang diperlukan menjadi lebih kecil, memungkinkan akses paralel cache (setiap subset dapat diakses satu kali tetapi tidak tergantung pada subset lainnya).
Ada lebih khusus ketika datang untuk menyinkronkan cache / akses memori antara core virtual yang berbeda, beberapa unit pemrosesan independen per inti dan akhirnya beberapa prosesor pada satu mainboard (yang ada papan perumahan sebanyak 48 prosesor dan banyak lagi).
Ini pada dasarnya adalah ide saat ini mengapa kita memiliki garis cache. Manfaat membaca di depan sangat tinggi dan kasus terburuk membaca byte tunggal dari cache-line dan tidak pernah membaca sisanya lagi sangat tipis karena probabilitasnya sangat tipis.
Ukuran cache-line (64) adalah pilihan trade-off yang dipilih secara bijak antara cache-line yang lebih besar membuatnya tidak mungkin untuk byte terakhir dari itu dibaca juga dalam waktu dekat, durasi yang diperlukan untuk mengambil garis cache lengkap dari memori (dan untuk menulisnya kembali) dan juga overhead dalam organisasi cache dan paralelisasi cache dan akses memori.