Di setiap tempat yang saya lihat, dikatakan double
lebih unggul float
dalam hampir semua hal. float
telah dibuat usang oleh double
di Jawa, jadi mengapa masih digunakan?
Saya banyak memprogram dengan Libgdx, dan mereka memaksa Anda untuk menggunakan float
(deltaTime, dll.), Tetapi bagi saya sepertinya double
lebih mudah untuk dikerjakan dalam hal penyimpanan dan memori.
Saya juga membaca Kapan Anda menggunakan float dan kapan Anda menggunakan double , tetapi jika float
benar-benar hanya baik untuk angka dengan banyak digit setelah titik desimal, lalu mengapa kita tidak bisa menggunakan salah satu dari banyak variasi saja double
?
Apakah ada alasan mengapa orang bersikeras menggunakan pelampung meskipun sebenarnya tidak memiliki keunggulan lagi? Apakah terlalu banyak pekerjaan untuk mengubah semuanya?
sumber
byte
danshort
danint
ketika adalong
?Jawaban:
LibGDX adalah kerangka kerja yang banyak digunakan untuk pengembangan game.
Dalam pengembangan game, Anda biasanya harus melakukan banyak angka secara real-time dan kinerja apa pun yang Anda bisa dapatkan. Itu sebabnya pengembang game biasanya menggunakan float setiap kali presisi float cukup baik.
Ukuran register FPU dalam CPU bukan satu-satunya hal yang perlu Anda pertimbangkan dalam kasus ini. Bahkan sebagian besar angka berat dalam pengembangan game dilakukan oleh GPU, dan GPU biasanya dioptimalkan untuk float, bukan ganda .
Dan kemudian ada juga:
yang semua sumber daya berharga yang Anda dapatkan dua kali lipat ketika Anda menggunakan float 32bit bukannya 64bit ganda.
sumber
Mengapung menggunakan setengah dari memori sebanyak dua kali lipat.
Mereka mungkin memiliki presisi kurang dari dua kali lipat, tetapi banyak aplikasi tidak membutuhkan presisi. Mereka memiliki jangkauan yang lebih besar daripada format titik tetap berukuran serupa. Oleh karena itu, mereka mengisi ceruk yang membutuhkan rentang angka yang luas tetapi tidak membutuhkan presisi tinggi, dan di mana penggunaan memori penting. Saya telah menggunakan mereka untuk sistem jaringan saraf besar di masa lalu, misalnya.
Bergerak di luar Jawa, mereka juga banyak digunakan dalam grafik 3D, karena banyak GPU menggunakannya sebagai format utama - di luar perangkat NVIDIA Tesla / AMD FirePro yang sangat mahal, floating point presisi ganda sangat lambat pada GPU.
sumber
Kompatibilitas Mundur
Ini adalah nomor satu alasan untuk menjaga perilaku dalam sudah ada bahasa / perpustakaan / ISA / etc.
Pertimbangkan apa yang akan terjadi jika mereka membawa kendaraan hias keluar dari Jawa. Libgdx (dan ribuan perpustakaan dan program lain) tidak akan berfungsi. Ini akan membutuhkan banyak upaya untuk mendapatkan semuanya diperbarui, sangat mungkin bertahun-tahun untuk banyak proyek (lihat saja transisi Pemecahan kompatibilitas mundur Python 2 ke Python 3). Dan tidak semuanya akan diperbarui, beberapa hal akan rusak selamanya karena pengelola mengabaikannya, mungkin lebih cepat dari yang seharusnya karena akan membutuhkan lebih banyak upaya daripada yang ingin diperbarui, atau karena tidak mungkin lagi mencapai apa yang seharusnya perangkat lunak mereka perkirakan melakukan.
Performa
64 bit ganda membutuhkan memori dua kali lipat dan hampir selalu lebih lambat untuk diproses daripada float 32 bit (pengecualian yang sangat jarang adalah di mana kemampuan float 32 bit diharapkan digunakan sangat jarang atau tidak sama sekali, sehingga tidak ada upaya yang dilakukan untuk mengoptimalkannya. Kecuali Anda mengembangkan perangkat keras khusus, Anda tidak akan mengalami ini dalam waktu dekat.)
Khusus yang relevan bagi Anda, Libgdx adalah perpustakaan permainan. Game memiliki kecenderungan lebih sensitif terhadap kinerja daripada kebanyakan perangkat lunak. Dan kartu grafis gaming (yaitu AMD Radeon dan NVIDIA Geforce, bukan FirePro atau Quadro) cenderung memiliki kinerja floating point 64 bit yang sangat lemah. Atas perkenan Anandtech, berikut ini perbandingan kinerja presisi ganda dengan kinerja presisi tunggal pada beberapa kartu gaming papan atas AMD dan NVIDIA yang tersedia (per awal 2016)
Perhatikan bahwa seri R9 Fury dan GTX 900 lebih baru daripada seri R9 200 dan GTX 700, sehingga kinerja relatif untuk floating point 64 bit menurun. Kembali cukup jauh dan Anda akan menemukan GTX 580, yang memiliki rasio 1/8 seperti seri R9 200.
1/32 dari kinerja adalah penalti yang cukup besar untuk dibayar jika Anda memiliki batasan waktu yang ketat dan tidak mendapatkan banyak dengan menggunakan ganda yang lebih besar.
sumber
Operasi atom
Selain apa yang telah dikatakan orang lain, kerugian spesifik Java dari
double
(danlong
) adalah bahwa penugasan untuk tipe primitif 64-bit tidak dijamin atomik . Dari Spesifikasi Bahasa Jawa, Edisi Java SE 8 , halaman 660 (penekanan ditambahkan):Yuck.
Untuk menghindari hal ini, Anda harus mendeklarasikan variabel 64-bit dengan
volatile
kata kunci, atau menggunakan bentuk sinkronisasi lain di sekitar penugasan.sumber
Tampaknya jawaban lain melewatkan satu poin penting: Arsitektur SIMD dapat memproses data lebih sedikit / lebih tergantung jika mereka beroperasi pada
double
ataufloat
struct (misalnya, delapan nilai float pada suatu waktu, atau empat nilai ganda pada suatu waktu).Ringkasan pertimbangan kinerja
float
mungkin lebih cepat pada CPU tertentu (misalnya, perangkat seluler tertentu).float
menggunakan lebih sedikit memori sehingga dalam kumpulan data besar itu dapat secara substansial mengurangi total memori yang dibutuhkan (hard disk / RAM) dan bandwidth yang dikonsumsi.float
dapat menyebabkan CPU mengkonsumsi daya lebih sedikit (saya tidak dapat menemukan referensi, tetapi jika tidak memungkinkan setidaknya tampaknya masuk akal) untuk perhitungan presisi tunggal dibandingkan dengan perhitungan presisi ganda.float
mengkonsumsi lebih sedikit bandwidth, dan dalam beberapa aplikasi yang penting.float
menggunakan sebanyak setengah dari memori cache dibandingkan dengan menggandakan.Ringkasan pertimbangan akurasi
float
sudah cukupdouble
toh memiliki presisi yang jauh lebih baikPertimbangan kompatibilitas
double
(itu karena produsen GPU mencoba meningkatkan jumlah inti grafis, dan jadi mereka mencoba untuk menyelamatkan sirkuit sebanyak mungkin di setiap inti, jadi mengoptimalkan untukfloat
memungkinkan untuk membuat GPU dengan lebih banyak inti di dalamnya)double
sebagai format internal (untuk operasi rendering 3D)Kiat umum
double
variabel sementara pada stack memberikan presisi ekstra secara gratis (presisi ekstra tanpa penalti kinerja).float
, tetapi mungkin nilai yang terbatas jika Anda menggunakandouble
)float
atau hanyadouble
sangat membantu kompiler untuk SIMD-ify instruksi.Lihat komentar di bawah dari PeterCordes untuk wawasan lebih lanjut.
sumber
double
temporaries hanya gratis di x86 dengan FPU x87, bukan dengan SSE2. Auto-vectorizing loop dengandouble
temporaries berarti membongkarfloat
kedouble
, yang mengambil instruksi tambahan, dan Anda memproses setengah karena banyak elemen per vektor. Tanpa auto-vektorisasi, konversi biasanya dapat terjadi dengan cepat saat memuat atau menyimpan, tetapi itu berarti instruksi tambahan saat Anda mencampur float dan menggandakan ekspresi.Terlepas dari alasan lain yang disebutkan:
Jika Anda memiliki data pengukuran, baik itu tekanan, arus, arus, tegangan atau apa pun, ini sering dilakukan dengan perangkat keras yang memiliki ADC.
ADC biasanya memiliki 10 atau 12 bit, 14 atau 16 bit lebih jarang. Tapi mari kita tetap pada bit 16 - jika mengukur sekitar skala penuh, Anda memiliki akurasi 1/65535. Itu berarti perubahan dari 65534/65535 menjadi 65535/65535 hanyalah langkah ini - 1/65535. Itu kira-kira 1.5E-05. Keakuratan float adalah sekitar 1E-07, jadi jauh lebih baik. Itu berarti Anda tidak kehilangan apa pun dengan menggunakan
float
untuk menyimpan data ini.Jika Anda melakukan perhitungan berlebihan dengan pelampung, Anda berkinerja lebih buruk daripada dengan
doubles
dalam hal akurasi, tetapi seringkali Anda tidak membutuhkan akurasi itu, karena Anda sering tidak peduli jika Anda baru saja mengukur tegangan 2 V atau 2.00002 V. Demikian pula , jika Anda mengubah tegangan ini menjadi tekanan, Anda tidak peduli jika Anda memiliki 3 bar atau 3,00003 bar.sumber