Apa fungsi fungsi Sys_PageIn () di Quake?

8

Saya perhatikan dalam proses inisialisasi Gempa asli, fungsi berikut disebut.

volatile int sys_checksum;

//  **lots of code**

void Sys_PageIn(void *ptr, int size)
{
    byte *x;
    int j,m,n;
//touch all memory to make sure its there.  The 16-page skip is to
//keep Win 95 from thinking we're trying to page ourselves in (we are
//doing that, of course, but there's no reason we shouldn't)
    x = (byte *)ptr;

    for (n=0 ; n<4 ; n++)
    {
        for (m=0; m<(size - 16 * 0x1000) ; m += 4)
        {
            sys_checksum += *(int *)&x[m];
            sys_checksum += *(int *)&x[m + 16 * 0x10000];
        }
    }
}

Saya pikir saya tidak cukup akrab dengan paging untuk memahami fungsi ini. void * ptr yang diteruskan ke fungsi adalah sepotong memori malloc () baru-baru ini yang berukuran byte besar. Ini adalah keseluruhan fungsi - j adalah variabel yang tidak direferensikan. Tebakan terbaik saya adalah sys_checksum int yang mudah menguap memaksa sistem untuk secara fisik membaca semua ruang yang hanya malloc (), mungkin untuk memastikan bahwa ruang-ruang ini ada dalam memori virtual? Apakah ini benar? Dan mengapa seseorang melakukan ini? Apakah karena alasan Win95 kuno?

Philip
sumber

Jawaban:

6

Tebakan Anda pada dasarnya benar, dan itu dilakukan sebagai optimasi (kemungkinan besar; saya hanya bisa berspekulasi tentu saja karena saya tidak menulis kode).

Sementara aplikasi di Windows tampaknya memiliki akses penuh ke seluruh rentang RAM di mesin (atau setidaknya kisaran yang dilaporkan oleh OS), dalam praktiknya OS mengvirtualisasikan akses aplikasi ke memori fisik aktual dan akan menyimpan wilayah (halaman) dari memori virtual ke disk saat dibutuhkan. Proses mentransfer daerah-daerah ini dari disk ke RAM fisik sering disebut "paging in" (ketika pergi dari disk ke RAM) atau "paging out" (ketika pergi dari RAM ke disk).

Disk IO lambat, dibandingkan dengan RAM, sehingga menghindari paging sangat ideal untuk mencapai kinerja maksimum. Maksud dari fungsi ini adalah untuk mencoba meminimalkan paging selama masa program dengan memaksa OS ke halaman semua memori di awal program - pemaksaan dilakukan dengan mencoba membaca dari semua memori.

Agaknya Windows 95 memiliki semacam kode untuk mendeteksi dan menghentikan perilaku ini, yang dikomentari oleh komentar tersebut diatasi dengan membaca memori dalam pola tertentu. Masuk akal bahwa OS akan melakukan ini, karena memaksa halaman-in lengkap seperti ini akan memaksa memori proses lain untuk keluar ke disk, mungkin memperlambat mereka .

Dapat dikatakan bahwa ini adalah perilaku yang dapat diterima untuk sebuah game karena pengguna umumnya hanya akan menjalankan game dan tidak mencoba untuk melakukan banyak tugas sambil bermain, sehingga mengorbankan kinerja proses lain yang mungkin berjalan tidak kejahatan itu.

Beberapa catatan lain:

  • Hal semacam ini sepertinya tidak akan berfungsi hampir sebaik hari ini seperti yang mungkin terjadi pada Windows 95. Sifat penjadwal OS telah berubah cukup banyak sejak saat itu, jadi itu belum tentu teknik yang saya sarankan untuk Anda terapkan kecuali Anda telah memaksa data profiler dan metrik untuk mendukung fakta bahwa upaya Anda bermanfaat.

  • volatileadalah petunjuk bagi implementasi untuk menghindari optimisasi agresif dari suatu objek yang dideklarasikan karena objek itu dapat berubah melalui implementasi yang tidak dapat diharapkan untuk diprediksi. Dengan kata lain, itu seperti bendera "jangan optimalkan aku". Dengan cara ini kompiler, bahkan jika ia menyadari bahwa variabel yang pada dasarnya tidak digunakan dengan cara yang signifikan, tidak akan mengoptimalkan pembacaan dari memori ke dalam variabel itu sebagai bagian dari operasinya.

  • j tidak digunakan mungkin hanya kekhilafan.


sumber
1

Raymond Chen menjawab ini secara langsung dalam posting di blognya The Old New Thing (Maximus Minimius memiliki sumber yang tepat ternyata hanya 3 tahun terlalu dini untuk penjelasan langsung): https://blogs.msdn.microsoft.com/oldnewthing / 20151111-00 /? P = 91972

Apa yang dilakukan kode ini adalah mengakses blok memori yang ditentukan oleh parameter ptr dan ukuran dalam pola yang tidak biasa: Bunyinya byte nol, kemudian byte pada offset 16 halaman, kemudian byte satu, lalu byte pada offset 16 halaman plus satu, dan seterusnya, berganti-ganti antara byte dan mitranya 16 halaman di depan.

Pola akses khusus ini di Windows 95 mengalahkan algoritma deteksi "pemindaian memori sekuensial".

Ingatlah bahwa komputer di era Windows 95 memiliki RAM 4MB. Misalkan Anda bekerja dalam dokumen untuk waktu yang lama. Akhirnya, Anda selesai, dan Anda menutup jendela atau memperkecilnya. Boom, sekarang desktop Anda terlihat dan wallpaper bitmap perlu di-paging. Jika layar Anda 1024 × 768 pada 16 bit per pixel, yang keluar untuk memori 1,5MB. Paging dalam memori 1,5MB berarti untuk bitmap berarti menendang 1,5MB memori yang digunakan untuk hal-hal lain, dan itu banyak memori untuk mesin yang hanya memiliki 4MB untuk bekerja (terutama karena banyak yang 4MB milik barang) yang tidak memenuhi syarat untuk dipindahkan). Fenomena yang kami lihat adalah mengecat ulang desktop Anda akan menghabiskan sebagian besar memori Anda.

Dan hal berikutnya yang Anda lakukan mungkin adalah meluncurkan aplikasi baru, yang akan mencakup wallpaper, sehingga memori wallpaper tidak lagi diperlukan. Jadi pada dasarnya kami membersihkan semua memori di sistem Anda untuk menangani blok besar memori yang hanya dapat diakses sekali.

Trik yang digunakan Windows 95 adalah mengawasi pola kesalahan halaman Anda, dan jika melihat Anda melakukan akses memori sekuensial, ia mulai menandai memori 16 halaman di belakang akses saat ini yang belum diakses baru-baru ini . Dalam kasus pemindaian berurutan lurus, ini berarti bahwa seluruh siklus buffer melalui jendela memori 64KB, terlepas dari ukuran buffer. Dengan trik ini, buffer 4MB hanya menghabiskan memori 64KB, dibandingkan dengan menggunakan semua memori di sistem Anda.

The Sys_Page­Infungsi khusus defeates detektor sekuensial-scan dengan sengaja akan kembali 16 halaman dan mengakses halaman lagi. Ini menyebabkannya ditandai baru-baru ini digunakan , menangkal yang baru-baru ini digunakan yang telah dilakukan oleh detektor sekuensial. Hasil: Halaman memori semua ditandai baru-baru ini digunakan dan tidak lagi kandidat utama untuk dikeluarkan.

Tyler Szabo
sumber
0

Membangkitkan ini, saya memperhatikan entri ini di situs Raymond Chen baru-baru ini: http://blogs.msdn.com/b/oldnewthing/archive/2012/08/13/10334566.aspx

Mengapa saya di kredit Gempa? Saya tidak ingat apa yang saya lakukan secara spesifik ... saran yang saya berikan hampir pasti terkait dengan manajemen memori dan pertukaran.

Ini menunjukkan bahwa setidaknya ada kemungkinan yang layak bahwa fungsi ini adalah hasil dari saran Raymond (dan ketika Raymond Chen mengatakan "Anda perlu melakukan ini" setidaknya ada kemungkinan yang layak bahwa ia benar).

Sangat mudah untuk dilupakan saat ini, tetapi pada tahun 1996 rata-rata PC gamer mungkin memiliki RAM 16mb, maks , dan Quake adalah monster mutlak dari sebuah program. Pada masa itu, hard disk yang digunakan untuk menggiling tanpa henti karena paging, dan menarik semua memori yang dialokasikan dengan cara ini akan (setidaknya) membantu mencegah file halaman dari harus disentuh saat runtime, yang bisa menyebabkan kios macet. apa saja hingga satu detik atau lebih.

Maximus Minimus
sumber