Memori Perangkat Write-Combining Dapat Menggabungkan Store CPU Sebelum I/O
Serangkaian store CPU ke memori perangkat tidak selalu berubah menjadi rangkaian transaksi bus yang identik. Pada mapping write-combining, prosesor dapat menampung store yang berdekatan lalu mengirimkannya sebagai transfer yang lebih besar. Perilaku ini cocok untuk framebuffer dan region perangkat lain yang dirancang menerima penulisan blok, tetapi asumsi tentang ordering dan bentuk transaksi menjadi lebih terbatas.
Linux menyediakan kelas mapping ini melalui antarmuka seperti ioremap_wc(). Semantiknya berbeda dari mapping ioremap() default yang digunakan untuk control register biasa.
Write combining mengubah kontrak akses memori
Mapping ioremap() normal ditujukan untuk register perangkat. Dalam model portabel driver Linux, mapping ini bersifat uncached, non-speculative, tidak mengulang akses, dan tidak melakukan write combining. Operasi I/O individual tetap diskret, bukan digabungkan menjadi write yang lebih besar oleh semantik mapping CPU.
ioremap_wc() sengaja melonggarkan kontrak tersebut. Store dapat digabungkan, operasi dapat diurutkan ulang selama masih sesuai dengan memory model yang berlaku, dan prosesor dapat menunda propagasi sambil mengumpulkan write. Aktivitas bus yang dihasilkan karena itu dapat berbeda dari urutan store yang terlihat pada source code.
store CPU 0 ----\
store CPU 1 -----+--> buffer write-combining --> transaksi perangkat
store CPU 2 -----+
store CPU 3 ----/Diagram tersebut menunjukkan pola yang diizinkan, bukan jaminan ukuran transaksi. Prosesor dapat melakukan flush pada buffer yang belum penuh, sehingga logika perangkat tidak boleh bergantung pada asumsi bahwa setiap kelompok store selalu menjadi satu transfer penuh.
Region data dan control register memerlukan semantik berbeda
Write combining berguna ketika tujuan berperilaku seperti memori. Framebuffer, aperture, atau buffer milik perangkat dapat menerima write independen pada suatu region tanpa memberikan side effect pada setiap store. Penggabungan beberapa store dapat mengurangi jumlah transaksi untuk memindahkan satu blok data.
Control register memiliki kontrak berbeda. Sebuah register write dapat mengakui interrupt, memajukan queue, menjalankan engine, atau memilih state untuk operasi berikutnya. Penggabungan, pengulangan, atau perubahan urutan akses tersebut dapat mengubah perilaku perangkat. Register semacam ini tetap memerlukan mapping device-I/O normal beserta aturan accessornya, kecuali spesifikasi hardware secara eksplisit menetapkan model lain yang aman.
Untuk resource PCI, Linux juga mengaitkan kelayakan write combining dengan atribut resource. Dokumentasi kernel menyatakan bahwa ioremap_wc() umumnya aman untuk region PCI MMIO yang ditandai IORESOURCE_PREFETCH; driver tidak dapat menganggap sembarang region BAR cocok untuk mapping tersebut.
Urutan store tidak menentukan urutan transaksi
Urutan pada source code bukan primitive ordering I/O untuk memori write-combining. CPU dapat mempertahankan store di combining buffer lalu mempropagasikannya kemudian. Region buffer yang terpisah juga dapat terlihat dalam urutan yang lebih lemah dibandingkan mapping device-register biasa.
Hal ini menjadi relevan ketika software mengisi buffer perangkat lalu menulis control register yang memerintahkan perangkat untuk mengonsumsinya:
write ke buffer write-combining
|
v
batas ordering yang diperlukan
|
v
MMIO doorbell atau control writeBatas tersebut merupakan bagian dari protokol perangkat. Linux menyediakan antarmuka I/O dan memory barrier yang menyesuaikan arsitektur untuk kasus seperti ini; primitive yang tepat bergantung pada mapping dan relasi ordering yang diperlukan driver. Compiler barrier biasa tidak menggantikan operasi ordering I/O pada hardware.
Linux juga menyediakan io_stop_wc() untuk tujuan yang lebih sempit: mencegah akses write-combining sebelum pemanggilan digabungkan dengan akses write-combining setelahnya. Operasi ini mengatur batas combining, bukan seluruh kebutuhan ordering yang mungkin ada antara memori, MMIO, dan DMA.
Flush parsial merupakan bagian dari realitas antarmuka
Combining buffer adalah resource mikroarsitektur yang terbatas. Jumlah buffer, kebijakan eviction, dan bentuk transaksi yang dikirim merupakan detail spesifik prosesor, bukan jaminan portabel bagi driver. Interrupt, pergantian konteks, store lain yang bersaing, atau kondisi implementasi lain dapat berkontribusi pada flush sebelum software memenuhi region yang diharapkan dapat digabungkan.
Perangkat yang diekspos melalui memori write-combining karena itu harus menerima partial write yang legal bagi antarmuka yang disediakannya. Software dapat mengatur store yang aligned dan berurutan untuk mendorong transfer yang efisien, tetapi bentuk paket yang sering terlihat tidak dapat dianggap sebagai jaminan arsitektural.
Perbedaan ini relevan saat melakukan analisis performa. Trace yang memperlihatkan transaksi besar pada satu prosesor hanya menunjukkan perilaku terukur untuk platform dan workload tersebut. Hasil itu tidak menetapkan batas transaksi yang sama pada generasi CPU atau implementasi interconnect lain.
Tipe mapping merupakan keputusan correctness
Write combining sering dibahas sebagai optimasi throughput, tetapi pemilihannya sekaligus memilih semantik akses yang lebih lemah. Region perangkat harus mendukung semantik tersebut sebelum pertimbangan performa diterapkan.
Pemisahan yang aman bersifat arsitektural: region bulk yang dirancang menerima write seperti memori dapat memakai mapping write-combining ketika platform dan atribut resource mengizinkannya; register dengan side effect tetap memakai mapping dan accessor device-I/O. Operasi ordering eksplisit kemudian menghubungkan jalur data dengan operasi kontrol pada titik yang diwajibkan protokol hardware.
Dengan pemisahan ini, penggabungan transaksi tetap menjadi kebebasan implementasi, bukan dependensi tidak sengaja pada antarmuka perangkat.