Apa manfaat dari pembatasan bingkai per detik? (Jika ada)

13

Saya sedang mengerjakan permainan sederhana di OpenGL, menggunakan SDL untuk inisialisasi tampilan dan input, dan ini muncul dalam hal waktu saya memiliki dua opsi yang tersedia untuk saya. Nomor satu yang hanya tidur untuk optimalTimePerFrame - theTimeTakenToRender, ketika optimalTimePerFrame dalam hitungan detik = 1 / theFramerateCap. (Saya tidak sepenuhnya yakin apakah ini perlu, karena ini setara dengan menggunakan vsync, yang mungkin lebih akurat. Jika asumsi saya benar maka tolong katakan padaku apakah SDL + OpenGL memiliki vsync secara default, dan jika tidak seberapa untuk mengaktifkannya.) Yang lain adalah untuk mengukur waktu sejak frame terakhir diberikan, dan hanya menyesuaikan gerakan yang sesuai. (Semakin pendek waktu yang dibutuhkan untuk membuat bingkai, entitas yang kurang jauh bergerak dalam bingkai itu). Dalam hal kinerja, dan penurunan flicker dll, apa kelebihan dan kekurangan dari kedua metode ini?

w4etwetewtwet
sumber

Jawaban:

15

Jika waktu frame Anda tidak dapat diprediksi (apakah ini adalah kesalahan Anda atau tidak; OS mungkin menggunakan sumber daya sesekali, dll), membatasi ke frame rate yang dapat diprediksi yang sedikit lebih rendah dari framerate Anda yang dapat dicapai akan banyak membantu latensi yang dapat diprediksi , yang dapat membuat game terasa jauh lebih baik.

Mengubah berapa lama antara saat Anda memproses input dan membuat perubahan yang terkait dengan input itu bisa terasa buruk - bahkan jika rata-rata Anda mencapai latensi yang lebih sedikit di antara keduanya, "jitter" dapat terlihat oleh manusia (secara sadar atau tidak sadar).

Lihat presentasi Microsoft GameFest What's in a Frame: Tearing, Latency, dan Frame Rate untuk beberapa wawasan di sini. Carmack juga memiliki serangkaian posting blog yang berguna dalam hal ini.

Perlu diketahui juga bahwa beberapa matematika dapat rusak ketika Anda menjalankan frame menggunakan deltaTnilai-nilai rendah - atau bahkan ketika Anda menggunakan variabel deltaTsama sekali (hal-hal dapat menjadi lebih sulit atau bahkan sulit dilakukan dengan cara "stabil" dan dapat diprediksi, yang penting untuk hal-hal seperti replay dan beberapa bentuk sinkronisasi jaringan). Lihat Memperbaiki Tanda Waktu Anda untuk beberapa wawasan di sini.

Leander
sumber
1
(Omong-omong, saya akan sangat menyarankan tidak membatasi dengan cara "tidur"; mencari tahu apa situasi vsync Anda pada platform Anda dan menggunakan vsync untuk mengarahkan Anda. Ini jauh lebih mudah diprediksi dan biasanya menggunakan lebih sedikit sumber daya.)
leander
Terima kasih, saya pasti akan mencoba untuk membatasi framerate. Apakah Anda tahu cara mengaktifkan vsync menggunakan SDL?
w4etwetewtwet
1
Di SDL 2.0, Anda dapat mengaktifkan vsync dengan mengirimkan flag SDL_RENDERER_PRESENTVSYNC ke panggilan SDL_CreateRenderer, mis.SDL_CreateRenderer(window, -1, SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTVSYNC);
TJS
12

Anda akan berakhir menggunakan CPU jauh lebih sedikit (multi tasker akan berterima kasih) dan orang-orang di perangkat seluler akan menghargai ini juga.

Vaughan Hilts
sumber
4
Belum lagi penggunaan daya yang lebih rendah (penting untuk perangkat seluler / laptop), dan lebih sedikit pembangkit panas.
zeel
Ini mengingatkan saya pada beberapa masalah gim, ketika FPS dalam menu tidak terbatas dan sangat tinggi, 900fps, dan itu benar-benar menekankan CPU / GPU -> temp lebih tinggi -> lebih banyak noise.
Kromster berkata mendukung Monica
10

Anda seharusnya tidak pernah, pernah, pernah, pernah, menggunakan Sleep untuk mengontrol framerate .

Ini sudah berlalu sebelumnya dan saya akan merujuk Anda ke pertanyaan lain untuk diskusi tentang alasan mengapa. Satu hal yang tidak disebutkan di sana adalah bahwa pada kecepatan refresh modern 60Hz yang khas, dan dengan granularity panggilan Sleep 1 milidetik, sebenarnya tidak mungkin untuk Sleep untuk jumlah waktu yang tepat antara frame.

Saya tidak mengatakan bahwa menghasilkan CPU jika tidak ada yang dilakukan adalah hal yang buruk; jauh dari itu. Tapi itu tidak sama dengan mengendalikan framerate dan Sleep adalah solusi yang sesuai untuk yang pertama tetapi tidak yang terakhir.

Alih-alih memeriksa waktu yang telah berlalu, dan jika sudah waktunya untuk menjalankan sebuah bingkai, maka lakukanlah, jika tidak - dan jika Anda ingin menghasilkan CPU - Tidurlah untuk waktu minimum - 1 milidetik. Juga pastikan pengatur waktu tidur Anda diatur dengan tepat untuk platform Anda sehingga memberi Anda resolusi yang baik; yaitu bahwa ketika Anda mengeluarkan "Tidur (1)" panggilan Anda benar-benar memiliki kesempatan untuk benar-benar Tidur selama 1 milidetik, daripada sesuatu seperti 15, 20 atau 30 (yang akan terjadi sebaliknya). Saya percaya bahwa SDL akan melakukan ini secara otomatis untuk Anda.

Anda juga dapat membuat beberapa kelonggaran di dalamnya, sehingga jika semakin dekat waktu untuk menjalankan bingkai, Anda berhenti Tidur dan mulai berlari datar hingga bingkai berjalan, yang dapat membantu Anda menekan interval bingkai yang Anda inginkan dengan lebih akurat.

Apa yang akhirnya tampak adalah sejumlah panggilan Sleep (1) diselingi dengan frame sesekali, dan tidak apa-apa. Anda masih melepaskan CPU saat tidak membutuhkannya, tetapi frame Anda masih dapat berjalan tepat waktu.

Maximus Minimus
sumber
0

Seperti yang disebutkan sebelumnya, ini menurunkan penggunaan CPU. Di flipside, dan semakin penting, itu juga menguras masa pakai baterai. Sebagai contoh yang baik, FTL beroperasi pada hampir 100% CPU pada MBA saya. Akibatnya, baterai terkuras dalam> 2 jam dan berjalan sangat panas. (Sebagai hasil yang lebih langsung, saya mencopot pemasangan dan tidak lagi memutarnya ...). Tutup bingkai akan mencegah ini.

Keuntungan lain yang tidak disebutkan adalah, jika ini adalah permainan multipemain, Anda juga menyamakan kedudukan dengan memberikan pengalaman yang sama kepada semua orang.

Serapth
sumber
Framerate dan loop pembaruan game Anda tidak harus berjalan pada kecepatan yang sama, jadi memberi orang pengalaman yang sama tidak bergantung pada framerate saja.
Thomas