Ini untuk ARM.
GCC menyediakan __builtin___clear_cache
yang lakukan harus melakukan syscall cacheflush
. Namun itu mungkin memiliki peringatannya.
Hal penting di sini adalah Linux menyediakan panggilan sistem (khusus ARM) untuk membersihkan cache. Anda dapat memeriksa Android/Bionic flushcache untuk cara menggunakan system call ini. Namun saya tidak yakin jaminan seperti apa yang diberikan Linux saat Anda memanggilnya atau bagaimana penerapannya melalui cara kerja dalamnya.
Entri blog ini Cache dan Self-Modifying Code dapat membantu lebih lanjut.
Periksa halaman ini untuk daftar metode pembilasan yang tersedia di kernel linux:https://www.kernel.org/doc/Documentation/cachetlb.txt
Pembilasan Cache dan TLB Di Linux. David S. Miller
Ada serangkaian fungsi pembilasan rentang
2) flush_cache_range(vma, start, end);
change_range_of_page_tables(mm, start, end);
flush_tlb_range(vma, start, end);
3) void flush_cache_range(struct vm_area_struct *vma,unsigned long start, unsigned long end)
Here we are flushing a specific range of (user) virtual
addresses from the cache. After running, there will be no
entries in the cache for 'vma->vm_mm' for virtual addresses in
the range 'start' to 'end-1'.
Anda juga dapat memeriksa implementasi fungsi - http://lxr.free-electrons.com/ident?a=sh;i=flush_cache_range
Misalnya, di lengan - http://lxr.free-electrons.com/source/arch/arm/mm/flush.c?a=sh&v=3.13#L67
67 void flush_cache_range(struct vm_area_struct *vma, unsigned long start, unsigned long end)
68 {
69 if (cache_is_vivt()) {
70 vivt_flush_cache_range(vma, start, end);
71 return;
72 }
73
74 if (cache_is_vipt_aliasing()) {
75 asm( "mcr p15, 0, %0, c7, c14, 0\n"
76 " mcr p15, 0, %0, c7, c10, 4"
77 :
78 : "r" (0)
79 : "cc");
80 }
81
82 if (vma->vm_flags & VM_EXEC)
83 __flush_icache_all();
84 }
Di Linux versi x86 Anda juga dapat menemukan fungsi void clflush_cache_range(void *vaddr, unsigned int size)
yang digunakan untuk keperluan membersihkan rentang cache. Fungsi ini bergantung pada CLFLUSH
atau CLFLUSHOPT
instruksi. Saya akan merekomendasikan untuk memeriksa apakah prosesor Anda benar-benar mendukungnya, karena secara teori itu opsional.
CLFLUSHOPT
dipesan dengan lemah. CLFLUSH
awalnya ditentukan sebagai dipesan hanya oleh MFENCE
, tetapi semua CPU yang mengimplementasikannya melakukannya dengan wrt pemesanan yang kuat. tulis dan CLFLUSH
lainnya instruksi. Intel memutuskan untuk menambahkan instruksi baru (CLFLUSHOPT
) alih-alih mengubah perilaku CLFLUSH
, dan memperbarui manual untuk menjamin bahwa CPU masa depan akan mengimplementasikan CLFLUSH
seperti yang diperintahkan dengan kuat. Untuk penggunaan ini, Anda harus MFENCE
setelah menggunakan keduanya, untuk memastikan bahwa pembilasan dilakukan sebelum pemuatan apa pun dari tolok ukur Anda (bukan hanya penyimpanan).
Sebenarnya x86 menyediakan satu lagi instruksi yang mungkin berguna:CLWB
. CLWB
membilas data dari cache ke memori tanpa (harus) mengeluarkannya, membiarkannya bersih tetapi masih tersimpan dalam cache. clwb
pada SKX tidak seperti clflushopt
, meskipun
Perhatikan juga bahwa petunjuk ini koheren cache. Eksekusinya akan memengaruhi semua cache dari semua prosesor (inti prosesor) di sistem.
Ketiga instruksi ini tersedia dalam mode pengguna. Dengan demikian, Anda dapat menggunakan assembler (atau intrinsik seperti _mm_clflushopt
) dan buat void clflush_cache_range(void *vaddr, unsigned int size)
Anda sendiri di aplikasi ruang pengguna Anda (tetapi jangan lupa untuk memeriksa ketersediaannya, sebelum penggunaan sebenarnya).
Jika saya mengerti dengan benar, jauh lebih sulit untuk bernalar tentang ARM dalam hal ini. Keluarga prosesor ARM jauh lebih tidak konsisten daripada keluarga prosesor IA-32. Anda dapat memiliki satu ARM dengan cache berfitur lengkap, dan satu lagi tanpa cache sama sekali. Lebih jauh lagi, banyak pabrikan dapat menggunakan MMU dan MPU yang disesuaikan. Jadi lebih baik bernalar tentang beberapa model prosesor ARM tertentu.
Sayangnya, sepertinya hampir tidak mungkin untuk melakukan perkiraan waktu yang masuk akal yang diperlukan untuk menghapus beberapa data. Kali ini dipengaruhi oleh terlalu banyak faktor termasuk jumlah baris cache yang dibilas, eksekusi instruksi yang tidak berurutan, status TLB (karena instruksi menggunakan alamat virtual sebagai argumen, tetapi cache menggunakan alamat fisik), jumlah CPU dalam sistem, beban aktual dalam hal operasi memori pada prosesor lain dalam sistem, dan berapa banyak baris dari jangkauan yang sebenarnya di-cache oleh prosesor, dan terakhir oleh kinerja CPU, memori, pengontrol memori, dan bus memori. Akibatnya, menurut saya waktu eksekusi akan sangat bervariasi di lingkungan yang berbeda dan dengan beban yang berbeda. Satu-satunya cara yang masuk akal adalah mengukur waktu flush pada sistem dan dengan beban yang mirip dengan sistem target.
Dan catatan terakhir, jangan bingung cache memori dan TLB. Keduanya adalah cache tetapi diatur dengan cara yang berbeda dan melayani tujuan yang berbeda. Cache TLB baru-baru ini menggunakan terjemahan antara alamat virtual dan fisik, tetapi bukan data yang ditunjukkan oleh alamat tersebut.
Dan TLB tidak koheren, berbeda dengan cache memori. Hati-hati, karena pembilasan entri TLB tidak mengarah pada pembilasan data yang sesuai dari cache memori.