Apakah ada CPU yang melakukan optimisasi penulisan cache L1 ini?

9

Ketika CPU dengan cache L1 melakukan penulisan, yang biasanya terjadi adalah (dengan asumsi bahwa baris cache yang sedang ditulisnya sudah ada dalam cache L1) cache (selain memperbarui data) menandai bahwa garis cache sebagai kotor , dan akan menulis garis keluar dengan data yang diperbarui di beberapa waktu kemudian.

Salah satu optimasi yang mungkin dilakukan adalah membuat cache membandingkan konten penulisan dan isi cache sebelumnya, dan jika keduanya sama, jangan tandai baris sebagai kotor. Karena ini memungkinkan cache untuk menghindari write-backs sesekali, saya dapat melihat bagaimana produsen CPU melihat ini sepadan dengan gerbang yang diperlukan untuk melakukan logika ini.

Pertanyaan saya: apakah ada CPU yang melakukan optimasi ini?

Latar belakang mengapa saya bertanya: Saya sedang menulis beberapa kode yang perlu memiliki akses memori yang konstan; yaitu, seseorang yang dapat mendengarkan perilaku cache seharusnya tidak dapat menyimpulkan apa yang saya lakukan. Beberapa akses saya adalah menulis, dan dengan cara yang jelas untuk menerapkan kode ini, banyak penulisan akan menulis data yang sama yang sudah ada di sana. Saya perlu melakukan penulisan karena, tergantung pada data, data yang saya tulis mungkin sama atau tidak sama, dan penting untuk melakukan tindakan yang sama. Jika CPU mengoptimalkan dengan tidak benar-benar menulis 'tidak ada perubahan-tulis', itu berarti bahwa perilaku cache akan bervariasi tergantung pada apa yang saya lakukan, yang akan menumbangkan tujuan saya.

Jadi, adakah CPU yang mencoba mengoptimalkan penulisan dengan cara ini?

ponco
sumber
11
Dikatakan bahwa ada dua masalah yang benar-benar sulit dalam ilmu komputer: pembatalan cache, penamaan sesuatu dengan baik, dan kesalahan satu per satu. Ini adalah contoh mengapa yang pertama rumit.
Mason Wheeler
@poncho Anda mengatakan bahwa "seseorang yang dapat mendengarkan perilaku cache tidak boleh menyimpulkan apa yang saya lakukan." Sekarang jika beberapa CPU menerapkan fitur "smart write-back" ini yang tidak membatalkan cache kecuali jika data benar-benar diperbarui, maka dengan naik satu tingkat lebih jauh dari CPU dalam hirarki memori, orang akan dapat mengamati lalu lintas / waktu perbedaan antara menulis nyata dan menulis boneka. Apakah ini yang Anda khawatirkan?
TheCodeArtist
@poncho Juga pertanyaan sebenarnya Anda tampaknya tentang menerapkan mode hak istimewa / aman yang lebih baik yang tidak membocorkan informasi penggunaan. Mungkin Anda harus bertanya itu? ...
TheCodeArtist
1
@TheCodeArtist: yah, sudah ada serangan sidechannel cryptographical yang diterbitkan di mana suatu enkripsi rutin dapat diserang oleh program lain yang berjalan pada inti berbeda dari CPU yang sama, dengan memiliki program serangan memantau cache bersama. Saya percaya program semacam itu berpotensi mendeteksi apakah garis cache L1 memerah, dan karenanya dapat menyimpulkan informasi tentang program yang saya minati, jika CPU melakukan optimasi yang sedang dibahas. Saya tidak berbicara tentang 'mode aman', karena saya tidak menganggap kemampuan untuk memodifikasi CPU atau OS.
ponco
4
Bahkan jika ini benar hari ini, itu tidak dijamin benar besok.
pjc50

Jawaban:

4

Dari jam pencarian, saya tidak dapat menemukan CPU yang menggunakan optimasi khusus ini. Sebagian besar optimasi yang disebutkan biasanya terkait dengan hit / miss dengan operasi baca / tulis dan akses data:

(halaman 7 dan) https://cseweb.ucsd.edu/classes/fa14/cse240A-a/pdf/08/CSE240A-MBT-L15-Cache.ppt.pdf

Namun, itu tidak berarti bahwa optimasi ini tidak dapat dilakukan. Secara umum, dimungkinkan untuk secara program mengakses ukuran garis cache CPU. Dimungkinkan juga untuk mengakses nilai saat ini di register cache - tetapi agak berbahaya untuk melakukannya. Jika Anda mengakses register yang salah pada waktu yang buruk, Anda bisa merusak yang terkait dengan program yang sedang berjalan. Atau Anda dapat secara tidak sengaja memodifikasi konten dari baris yang Anda coba baca.

Memperoleh nilai saat ini dalam cache register

Selain itu, semua solusi teoritis memerlukan beberapa bentuk implementasi perangkat lunak (assembler). Yang paling dekat yang saya temukan berkaitan dengan arsitektur ARM, yang muncul untuk memungkinkan manipulasi cache. Selain itu, Anda juga perlu mengetahui ukuran garis cache untuk CPU yang Anda inginkan. Anda dapat dengan hati-hati membaca konten cache ke lokasi sekunder dalam memori, dalam penambahan ukuran garis, dan membandingkannya dengan data yang akan ditulis ke register (atau jalur cache L1, dalam kasus ini).

Baca konten cache CPU

Dari sana, Anda dapat menyusun sistem berbasis perangkat lunak yang mencegah penulisan ulang yang identik. Meskipun ini sedikit disederhanakan, itu karena solusi harus berlaku untuk setiap CPU yang ada.

Kemungkinan lain yang saya temukan terkait dengan koherensi Cache:

Bagian yang relevan dari artikel Wikipedia tentang acche coherence

Poin utama yang menarik perhatian saya, sehubungan dengan masalah ini, adalah deskripsi Snarfing:

Ini adalah mekanisme di mana pengontrol cache mengawasi alamat dan data dalam upaya untuk memperbarui salinan lokasi memori sendiri ketika master kedua memodifikasi lokasi di memori utama. Ketika operasi tulis diamati ke lokasi yang memiliki salinan dari cache, pengontrol cache memperbarui salinan sendiri dari lokasi memori snarfed dengan data baru.

Dengan kata lain, mungkin ada mekanisme yang sudah ada. Hanya saja mereka mungkin tidak digunakan untuk optimasi yang Anda sarankan. Anda harus mengimplementasikan perangkat lunak yang melakukan perbandingan baca / tulis.

Komunitas
sumber
Dimungkinkan juga untuk mengakses nilai saat ini di register cache - tetapi agak berbahaya untuk melakukannya. Hah, ini tidak masuk akal. Apakah maksud Anda register CPU? Compiler yang dihasilkan atau kode asm yang ditulis tangan menggunakan register untuk menyimpan nilai-nilai yang beroperasi pada ...
Peter Cordes
Jika Anda mencoba menerapkan ini dalam perangkat lunak, Anda hanya perlu membuat kode pembuat kompiler yang if (mem != x) { mem = x; }bukan mem = x;. Ini hanya kadang-kadang optimasi untuk garis cache bersama dalam program multi-utas, karena menulis mengganggu pembacaan utas lainnya.
Peter Cordes
1
"snarfing" tidak ada hubungannya dengan ini. Itu hanya pengintaian pasif. Cache CPU menggunakan MESI sehingga mereka dapat memiliki cache write-back yang koheren.
Peter Cordes
@PeterCordes Jika Anda menemukan jawaban saya tidak menyenangkan, saya minta maaf. Namun, tampaknya Anda memiliki lebih banyak wawasan daripada saya tentang masalah ini. Jadi, mengapa tidak menjawab sendiri pertanyaan itu? Respons saya jelas tidak memadai oleh standar Anda ...
3

Menulis ke cache L1 adalah operasi yang sangat, sangat kritis.

Menulis kembali data yang sama persis agak jarang. Optimasi yang mempercepat dalam kasus khusus ini tidak akan mendapatkan banyak peningkatan total.

Di sisi lain, optimasi ini memerlukan perbandingan data lama dan data baru pada setiap penulisan ke memori cache. Yang membuat ini lebih buruk, adalah bahwa data yang ditulis harus benar-benar tersedia pada saat penulisan!

Itu biasanya tidak terjadi pada CPU modern. Data yang akan ditulis mungkin masih dihitung misalnya. Cache masih dapat melanjutkan, memuat garis cache jika perlu, menandai garis cache sebagai telah dimodifikasi dan seterusnya, bahkan sebelum perhitungan selesai. Semua pembukuan sudah dapat dilakukan kecuali untuk modifikasi baris cache yang sebenarnya. Jika Anda ingin membandingkan hasil yang baru ditulis dan data jalur cache lama, itu tidak mungkin.

Sebagai contoh, jika Anda memiliki kode C a [i] = x / y; divisi x / y membutuhkan waktu yang sangat lama untuk bekerja pada kebanyakan CPU. Namun, sebagian besar pekerjaan yang diperlukan untuk menangani menyimpan hasil ke [i] telah terjadi jauh sebelum divisi selesai; satu-satunya hal yang hilang adalah perpindahan delapan byte hasil ke baris cache. Operasi pembilasan garis cache akan secara otomatis menunggu sampai pembagian selesai. Operasi yang membaca [i] kemungkinan akan diarahkan untuk mendapatkan hasil langsung dari pembagi.

gnasher729
sumber
Tembolok yang menggunakan MESI untuk koherensi masih dapat melakukan RFO, tetapi jika data membandingkan yang sama setelah siap, biarkan baris dalam kondisi Eksklusif alih-alih Diubah. Alasan sebenarnya hal itu tidak dilakukan dalam perangkat keras adalah karena biaya tambahan cache dibaca sebagai data berkomitmen untuk cache, dan akan memerlukan semacam siklus baca / bandingkan / tulis atom (dengan pengaturan opsional bit kotor) yang membuatnya menyedot untuk implementasi pipelined.
Peter Cordes
1

Salah satu pengoptimalan yang mungkin adalah membuat cache membandingkan konten penulisan dan isi cache sebelumnya, dan jika itu sama, jangan tandai baris sebagai kotor

Tidak akankah optimasi seperti itu menggandakan waktu yang dibutuhkan CPU untuk menulis sesuatu ke dalam cache? Karena setiap baris cache menulis sekarang akan disertai dengan operasi perbandingan, yang tidak gratis.

Jadi, sebenarnya optimasi sekarang akan tergantung pada faktor yang sangat samar: berapa kali rata-rata perangkat lunak menulis ulang memori yang dapat di-cache dengan data yang sama.

Vladislav Rastrusny
sumber
Perbandingan ini akan diimplementasikan dalam logika CPU. Itu tidak akan memerlukan operasi CPU tambahan, tetapi waktu sinyal mungkin meningkat, yang bisa menjadi masalah atau tidak.
ziggystar
@ziggystar Ya, saya bukan master perangkat keras, tapi saya terbiasa dengan pemikiran bahwa semuanya datang dengan biaya. Begitu juga membandingkan operasi terhadap garis cache. Mungkin cepat. Tetapi ini masih biaya. Dan saya pikir pelaksana memutuskan untuk tidak membayarnya. Bahkan mungkin setelah berpikir dan mengukur.
Vladislav Rastrusny
1
Tetapi Anda berbicara tentang waktu, di mana biaya mungkin hanya berupa peningkatan jumlah gerbang.
ziggystar
1
@ziggystar: Ini bukan hanya gerbang. Ketika data dikirim ke cache, biasanya proses pengiriman data dapat menandai baris cache sebagai yang dimodifikasi. Dengan "optimisasi" ini, data lama dan data baru harus melewati gerbang ini yang akan menyebabkan beberapa penundaan, dan hanya dengan demikian cache dapat dibatalkan. Anda harus memeras semua ini ke dalam satu siklus prosesor, jika tidak menulis ke garis cache tiba-tiba membutuhkan dua siklus. Dan sekarang untuk membuat segalanya lebih rumit, pertimbangkan apa yang terjadi ketika saya menulis delapan kata berturut-turut ke baris cache.
gnasher729
1
Dan masing-masing penulisan ini menunda keputusan apakah garis cache dimodifikasi. Jadi ketika penulisan kedua terjadi, baris cache tidak tahu apakah itu dimodifikasi atau belum (belum). Ini akan menjadi menyenangkan.
gnasher729