Saya melakukan beberapa tes waktu dan juga membaca beberapa artikel seperti ini (komentar terakhir), dan sepertinya dalam Rilis nilai build, float dan double membutuhkan waktu pemrosesan yang sama.
Bagaimana ini mungkin? Ketika float kurang tepat dan lebih kecil dibandingkan dengan nilai ganda, bagaimana CLR bisa berlipat ganda ke dalam waktu pemrosesan yang sama?
c#
.net
clr
performance
Joan Venge
sumber
sumber
Jawaban:
Pada prosesor x86, setidaknya,
float
dandouble
masing-masing akan dikonversi menjadi 10-byte nyata oleh FPU untuk diproses. FPU tidak memiliki unit pemrosesan terpisah untuk berbagai jenis floating-point yang didukungnya.Saran kuno yang
float
lebih cepat daripada yangdouble
diterapkan 100 tahun yang lalu ketika sebagian besar CPU tidak memiliki FPU bawaan (dan hanya sedikit orang yang memiliki chip FPU terpisah), jadi sebagian besar manipulasi floating-point dilakukan dalam perangkat lunak. Pada mesin ini (yang didukung oleh uap yang dihasilkan oleh lubang lava), itu adalah lebih cepat untuk menggunakanfloat
s. Sekarang satu-satunya manfaat nyata untukfloat
s adalah bahwa mereka mengambil lebih sedikit ruang (yang hanya penting jika Anda memiliki jutaan).sumber
Itu tergantung pada sistem 32-bit atau 64-bit . Jika Anda mengompilasi ke 64-bit, penggandaan akan lebih cepat. Dikompilasi menjadi 32-bit pada 64-bit (mesin dan OS) membuat float sekitar 30% lebih cepat:
public static void doubleTest(int loop) { Console.Write("double: "); for (int i = 0; i < loop; i++) { double a = 1000, b = 45, c = 12000, d = 2, e = 7, f = 1024; a = Math.Sin(a); b = Math.Asin(b); c = Math.Sqrt(c); d = d + d - d + d; e = e * e + e * e; f = f / f / f / f / f; } } public static void floatTest(int loop) { Console.Write("float: "); for (int i = 0; i < loop; i++) { float a = 1000, b = 45, c = 12000, d = 2, e = 7, f = 1024; a = (float) Math.Sin(a); b = (float) Math.Asin(b); c = (float) Math.Sqrt(c); d = d + d - d + d; e = e * e + e * e; f = f / f / f / f / f; } } static void Main(string[] args) { DateTime time = DateTime.Now; doubleTest(5 * 1000000); Console.WriteLine("milliseconds: " + (DateTime.Now - time).TotalMilliseconds); time = DateTime.Now; floatTest(5 * 1000000); Console.WriteLine("milliseconds: " + (DateTime.Now - time).TotalMilliseconds); Thread.Sleep(5000); }
sumber
Math
bekerja dengan ganda. Tapi Anda salah membaca posting saya: tes saya menunjukkan kinerja saya mengambang lebih baik.float
dandouble
hampir identik. Perbedaan kurang dari 0,3% ketika dirata-ratakan pada banyak uji coba independen, di mana setiap uji coba melakukan operasi perkalian, bagi, dan penambahan pada variabel yang dirantai secara berurutan (untuk menghindari pengoptimalan compiler menghalangi). Saya mencoba rangkaian tes kedua denganMath.Sin()
danMath.Sqrt()
dan juga mendapatkan hasil yang sama.Saya memiliki proyek kecil di mana saya menggunakan CUDA dan saya ingat bahwa float juga lebih cepat dari dua kali lipat di sana. Untuk sekali lalu lintas antara Host dan Perangkat lebih rendah (Host adalah CPU dan RAM "normal" dan Perangkat adalah GPU dan RAM yang sesuai di sana). Tetapi bahkan jika data berada di Perangkat sepanjang waktu itu lebih lambat. Saya rasa saya pernah membaca bahwa ini telah berubah baru-baru ini atau seharusnya berubah dengan generasi berikutnya, tetapi saya tidak yakin.
Jadi tampaknya GPU tidak dapat menangani presisi ganda secara native dalam kasus tersebut, yang juga menjelaskan mengapa GLFloat biasanya digunakan daripada GLDouble.
(Seperti yang saya katakan itu hanya sejauh yang saya ingat, baru saja menemukan ini saat mencari float vs. double pada CPU.)
sumber
Masih ada beberapa kasus di mana float lebih disukai - dengan pengkodean OpenGL misalnya, jauh lebih umum menggunakan tipe data GLFloat (umumnya dipetakan langsung ke float 16 bit) karena lebih efisien pada sebagian besar GPU daripada GLDouble.
sumber