Saya menggunakan platform Linux dan 8-core x86. Pertama, bagaimana cara menemukan ukuran baris cache.
$ getconf LEVEL1_DCACHE_LINESIZE
64
Berikan nilai sebagai definisi makro ke kompiler.
$ gcc -DLEVEL1_DCACHE_LINESIZE=`getconf LEVEL1_DCACHE_LINESIZE` ...
Saat dijalankan sysconf(_SC_LEVEL1_DCACHE_LINESIZE)
dapat digunakan untuk mendapatkan ukuran cache L1.
Untuk mengetahui ukurannya, Anda perlu mencarinya menggunakan dokumentasi prosesor, afaik tidak ada cara terprogram untuk melakukannya. Namun di sisi positifnya, sebagian besar jalur cache memiliki ukuran standar, berdasarkan standar intel. Pada garis cache x86 berukuran 64 byte, namun, untuk mencegah pembagian yang salah, Anda harus mengikuti pedoman prosesor yang Anda targetkan (intel memiliki beberapa catatan khusus pada prosesor berbasis netburst), umumnya Anda perlu menyelaraskan ke 64 byte untuk ini (intel menyatakan bahwa Anda juga harus menghindari melewati batas 16 byte).
Untuk melakukannya di C atau C++, Anda harus menggunakan aligned_alloc
standar function atau salah satu penentu khusus compiler seperti __attribute__((align(64)))
atau __declspec(align(64))
. Untuk mem-pad di antara anggota dalam sebuah struct untuk membaginya ke baris cache yang berbeda, Anda perlu memasukkan anggota yang cukup besar untuk menyelaraskannya ke batas 64 byte berikutnya
Cara sederhana lainnya adalah dengan cat saja /proc/cpuinfo:
grep cache_alignment /proc/cpuinfo
Tidak ada cara yang sepenuhnya portabel untuk mendapatkan ukuran cacheline. Namun jika Anda menggunakan x86/64, Anda dapat memanggil cpuid
instruksi untuk mendapatkan semua yang perlu Anda ketahui tentang cache - termasuk ukuran, ukuran cacheline, berapa level, dll...
http://softpixel.com/~cwright/programming/simd/cpuid.php
(gulir ke bawah sedikit, halamannya tentang SIMD, tetapi ada bagian yang mendapatkan cacheline.)
Untuk menyelaraskan struktur data Anda, juga tidak ada cara yang sepenuhnya portabel untuk melakukannya. GCC dan VS10 memiliki cara berbeda untuk menentukan perataan struct. Salah satu cara untuk "meretas" itu adalah mengisi struct Anda dengan variabel yang tidak digunakan hingga cocok dengan perataan yang Anda inginkan.
Untuk menyelaraskan mallocs() Anda, semua kompiler utama juga memiliki fungsi malloc yang selaras untuk tujuan itu.