Apa arti dari akses memori "non temporal" di x86

123

Ini adalah pertanyaan tingkat rendah. Dalam perakitan x86 ada dua instruksi SSE:

MOVDQA xmmi, m128

dan

MOVNTDQA xmmi, m128

Manual Pengembang Perangkat Lunak IA-32 mengatakan bahwa NT di MOVNTDQA adalah singkatan dari Non-Temporal , dan sebaliknya itu sama dengan MOVDQA.

Pertanyaan saya adalah, apa arti Non-Temporal ?

Nathan Fellman
sumber
6
Perhatikan bahwa SSE4.1 MOVNTDQA xmmi, m128adalah beban NT, sementara semua instruksi NT lainnya disimpan, kecuali prefetchnta. Jawaban yang diterima di sini sepertinya hanya berbicara tentang toko. Ini adalah apa yang saya dapat temukan tentang beban NT . TL: DR: semoga CPU melakukan sesuatu yang berguna dengan petunjuk NT untuk meminimalkan polusi cache, tetapi mereka tidak menimpa semantik memori WB "normal" yang diurutkan dengan kuat, jadi mereka harus menggunakan cache.
Peter Cordes
5
Pembaruan: Beban NT mungkin tidak berguna kecuali pada wilayah memori UCSW pada kebanyakan CPU (misalnya keluarga Intel SnB). Toko NT / streaming pasti berfungsi pada memori normal.
Peter Cordes
4
@ Peter: Maksudmu memori USWC kan? Saya belum pernah mendengar tentang memori UCSW atau USWC sebelumnya. Googling akronim yang salah tidak membantu :-)
Andrew Bainbridge
4
@ AndrewBainbridge: Ya, atribut jenis memori WC. Penggabungan Tulis Spekulatif yang Tidak Dapat Di-cache. Saya pikir saya menggunakan huruf besar UnCacheable dan mengingat bahwa itu seharusnya terdiri dari 4 huruf. : P
Peter Cordes

Jawaban:

147

Instruksi SSE Non-Temporal (MOVNTI, MOVNTQ, dll.), Jangan ikuti aturan koherensi cache normal. Oleh karena itu penyimpanan non-temporal harus diikuti dengan instruksi SFENCE agar hasilnya dapat dilihat oleh prosesor lain secara tepat waktu.

Ketika data diproduksi dan tidak (segera) dikonsumsi lagi, fakta bahwa operasi penyimpanan memori membaca baris cache penuh terlebih dahulu dan kemudian memodifikasi data cache merusak kinerja. Operasi ini mendorong data keluar dari cache yang mungkin diperlukan lagi untuk mendukung data yang tidak akan segera digunakan. Ini terutama berlaku untuk struktur data besar, seperti matriks, yang diisi dan kemudian digunakan nanti. Sebelum elemen terakhir dari matriks diisi, ukuran yang sangat besar akan menghapus elemen pertama, membuat cache penulisan tidak efektif.

Untuk situasi ini dan yang serupa, prosesor menyediakan dukungan untuk operasi tulis non-temporal. Non-temporal dalam konteks ini berarti data tidak akan segera digunakan kembali, jadi tidak ada alasan untuk menyimpannya. Operasi tulis non-temporal ini tidak membaca baris cache dan kemudian memodifikasinya; sebaliknya, konten baru langsung ditulis ke memori.

Sumber: http://lwn.net/Articles/255364/

Espo
sumber
15
Jawaban bagus, saya hanya ingin menunjukkan bahwa pada jenis prosesor dengan instruksi NT, bahkan dengan instruksi non-temporal (yaitu instruksi normal), cache baris tidak "dibaca dan kemudian diubah". Untuk instruksi normal yang menulis ke baris yang tidak ada di cache, baris dicadangkan di cache dan mask menunjukkan bagian mana dari baris yang up-to-date. Halaman web ini menyebutnya "tidak ada kios di toko": ptlsim.org/Documentation/html/node30.html . Saya tidak dapat menemukan referensi yang lebih tepat, saya hanya mendengar tentang ini dari orang-orang yang tugasnya mengimplementasikan simulator prosesor.
Pascal Cuoq
2
Sebenarnya ptlsim.org adalah situs web tentang simulator prosesor yang akurat-siklus, persis seperti yang dilakukan orang-orang yang memberi tahu saya tentang "tidak ada kios di toko". Sebaiknya saya juga menyebutkannya jika mereka melihat komentar ini: unisim.org
Pascal Cuoq
1
Dari jawaban dan komentar di sini stackoverflow.com/questions/44864033/… sepertinya SFENCEmungkin tidak diperlukan. Setidaknya di utas yang sama. Bisakah Anda juga melihat?
Serge Rogatch
1
@SergeRogatch itu tergantung pada skenario apa yang Anda bicarakan, tetapi ya ada skenario di mana sfencediperlukan untuk toko NT, sedangkan itu tidak pernah diperlukan hanya untuk toko normal. Toko NT tidak dipesan sehubungan dengan toko lain (NT atau tidak), seperti yang terlihat oleh utas lain , tanpa sfence. Namun, untuk membaca dari utas yang sama yang melakukan penyimpanan, Anda tidak perlu sfence: utas tertentu akan selalu melihat penyimpanannya sendiri dalam urutan program, terlepas dari apakah itu toko NT atau bukan.
BeeOnRope
40

Espo cukup tepat sasaran. Hanya ingin menambahkan dua sen saya:

Frasa "non temporal" berarti kurang lokalitas temporal. Cache mengeksploitasi dua jenis lokalitas - spasial dan temporal, dan dengan menggunakan instruksi non-temporal Anda memberi isyarat kepada prosesor bahwa Anda tidak mengharapkan item data digunakan dalam waktu dekat.

Saya sedikit skeptis tentang rakitan kode tangan yang menggunakan instruksi kontrol cache. Dalam pengalaman saya, hal-hal ini menyebabkan lebih banyak bug jahat daripada peningkatan kinerja yang efektif.

Pramod
sumber
pertanyaan tentang "perakitan kode tangan yang menggunakan instruksi kontrol cache." Saya tahu Anda secara eksplisit mengatakan "kode tangan" bagaimana dengan sesuatu seperti JavaVM. Apakah ini kasus penggunaan yang lebih baik? JavaVM / Compiler telah menganalisis perilaku statis dan dinamis dari program dan menggunakan instruksi non-temporal ini.
Tepuk
4
Memanfaatkan properti lokalitas yang diketahui (atau ketiadaan) dari domain bermasalah, algoritme, atau aplikasi Anda tidak boleh dijauhi. Menghindari polusi cache memang merupakan tugas pengoptimalan yang sangat menarik dan efektif. Juga, mengapa enggan untuk berkumpul? Ada banyak sekali peluang untuk memperoleh yang tersedia yang tidak mungkin dimanfaatkan oleh
kompiler
5
Memang benar bahwa programmer tingkat rendah yang berpengetahuan luas dapat mengungguli kompiler untuk kernel kecil. Ini bagus untuk menerbitkan makalah dan posting blog dan saya telah melakukan keduanya. Mereka juga merupakan alat didaktik yang baik, dan membantu memahami apa yang "sebenarnya" sedang terjadi. Namun, dalam pengalaman saya, dalam praktiknya, di mana Anda memiliki sistem nyata dengan banyak programmer yang mengerjakannya dan kebenaran serta pemeliharaan itu penting, manfaat pengkodean tingkat rendah hampir selalu lebih besar daripada risikonya.
Pramod
4
@Pramod argumen yang sama dengan mudah digeneralisasikan untuk pengoptimalan secara umum dan tidak benar-benar dalam ruang lingkup diskusi - jelas bahwa trade-off telah dipertimbangkan atau dianggap tidak relevan mengingat fakta bahwa kita sudah berbicara tentang instruksi non-temporal
awdz9nld
7

Menurut Panduan Pengembang Perangkat Lunak Arsitektur Intel® 64 dan IA-32, Volume 1: Arsitektur Dasar, bab "Pemrograman dengan Intel Streaming SIMD Extensions (Intel SSE)":

Penyimpanan Data Temporal vs. Non-Temporal

Data yang direferensikan oleh program dapat bersifat temporal (data akan digunakan lagi) atau non-temporal (data akan direferensikan sekali dan tidak akan digunakan kembali dalam waktu dekat). Misalnya, kode program umumnya bersifat temporal, sedangkan data multimedia, seperti daftar tampilan dalam aplikasi grafik 3-D, seringkali bersifat non-temporal. Untuk menggunakan cache prosesor secara efisien, biasanya diinginkan untuk menyimpan data temporal dan tidak menyimpan data non-temporal. Membebani cache prosesor dengan data non-temporal terkadang disebut sebagai "mencemari cache". Instruksi kontrol cacheability SSE dan SSE2 memungkinkan program untuk menulis data non-temporal ke memori dengan cara yang meminimalkan polusi cache.

Deskripsi beban non-temporal dan instruksi penyimpanan. Sumber: Panduan Pengembang Perangkat Lunak Arsitektur Intel 64 dan IA-32, Volume 2: Referensi Set Instruksi

BEBAN (MOVNTDQA — Memuat Petunjuk Selaras Non-Temporal Ganda Quadword)

Memuat quadword ganda dari operan sumber (operan kedua) ke operan tujuan (operan pertama) menggunakan petunjuk non-temporal jika sumber memori adalah tipe memori WC (penggabungan tulis) [...]

[...] prosesor tidak membaca data ke dalam hierarki cache, juga tidak mengambil baris cache yang sesuai dari memori ke dalam hierarki cache.

Perhatikan bahwa, seperti yang dikomentari Peter Cordes, ini tidak berguna pada memori WB (tulis kembali) normal pada prosesor saat ini karena petunjuk NT diabaikan (mungkin karena tidak ada prefetcher HW yang sadar NT) dan semantik muatan penuh yang diurutkan dengan kuat berlaku . prefetchntadapat digunakan sebagai beban pengurang polusi dari memori WB

STORE (MOVNTDQ — Simpan Integer yang Dikemas Menggunakan Petunjuk Non-Temporal)

Memindahkan integer yang dikemas dalam operan sumber (operan kedua) ke operan tujuan (operan pertama) menggunakan petunjuk non-temporal untuk mencegah caching data selama penulisan ke memori.

[...] prosesor tidak menulis data ke dalam hierarki cache, juga tidak mengambil baris cache yang sesuai dari memori ke dalam hierarki cache.

Menggunakan terminologi yang ditentukan dalam Kebijakan dan Performa Penulisan Cache , mereka dapat dianggap sebagai operasi tulis (no-write-alokasi, no-fetch-on-write-miss).

Terakhir, mungkin menarik untuk meninjau catatan John McAlpin tentang penyimpanan non-temporal .

chus
sumber
3
SSE4.1 MOVNTDQAhanya melakukan sesuatu yang khusus pada wilayah memori WC (Unacheable Write-Combining), misalnya RAM video. Ini sama sekali tidak berguna pada memori WB (tulis-balik) normal pada HW saat ini, petunjuk NT diabaikan dan semantik muatan penuh yang diurutkan dengan kuat berlaku. prefetchntadapat berguna, sebagai beban pengurang polusi dari memori WB. Apakah arsitektur x86 saat ini mendukung beban non-temporal (dari memori "normal")? .
Peter Cordes
2
Benar, penyimpanan NT berfungsi dengan baik pada memori WB, dan urutannya lemah, dan biasanya merupakan pilihan yang baik untuk menulis wilayah memori yang besar. Tapi beban NT tidak. Manual x86 di atas kertas memungkinkan petunjuk NT untuk melakukan sesuatu untuk memuat dari memori WB, tetapi dalam CPU saat ini tidak melakukan apa pun . (Mungkin karena tidak ada prefetcher NT-aware HW.)
Peter Cordes
Saya telah menambahkan info yang relevan ke jawabannya. Terima kasih banyak.
chus
1
@LewisKelsey: NT toko melakukan menggantikan jenis memori. Itulah mengapa mereka dapat diurutkan dengan lemah pada memori WB. Efek utama adalah menghindari RFO (tampaknya mereka mengirim pembatalan yang bahkan menghapus jalur kotor lainnya ketika mereka mencapai anggota). Mereka juga bisa terlihat rusak, jadi mereka tidak perlu menunggu sampai setelah penyimpanan cache-miss (biasa) yang sebelumnya dilakukan, atau sampai muatan cache-miss sebelumnya mendapatkan data. yaitu jenis kemacetan yang ditanyakan dalam Apakah memori di luar setiap inti selalu secara konseptual datar / seragam / sinkron dalam sistem multiprosesor? .
Peter Cordes
1
@LewisKelsey: Mesin pemesan memori yang jelas dapat menghentikan beban apa pun setelah penyimpanan UC yang seharusnya tidak dilakukan lebih awal, jika perlu. Selain itu, commit order tidak akan berlaku sampai toko berhenti dari back end yang rusak. Itu tidak dapat terjadi sampai setelah store-address uop dijalankan, di mana tipe memori untuk alamat tersebut dapat diperiksa. Sebuah uop alamat penyimpanan memeriksa TLB saat dijalankan; begitulah cara CPU dapat mendeteksi penyimpanan yang salah sebelum mereka pensiun. Itu tidak bisa menunggu sampai entri SB siap untuk berkomitmen ke L1d; pada saat itu eksekusi sudah lewat.
Peter Cordes