Tôi nhận thấy rằng một cấu trúc gói một phao đơn là chậm hơn đáng kể so với sử dụng một phao trực tiếp, với khoảng một nửa hiệu suất.Tại sao thêm một trường bổ sung để cấu trúc cải thiện đáng kể hiệu suất của nó?
using System;
using System.Diagnostics;
struct Vector1 {
public float X;
public Vector1(float x) {
X = x;
}
public static Vector1 operator +(Vector1 a, Vector1 b) {
a.X = a.X + b.X;
return a;
}
}
Tuy nhiên, khi bổ sung 'thêm' một trường bổ sung, một số ma thuật dường như xảy ra và thực hiện một lần nữa trở nên hợp lý hơn:
struct Vector1Magic {
public float X;
private bool magic;
public Vector1Magic(float x) {
X = x;
magic = true;
}
public static Vector1Magic operator +(Vector1Magic a, Vector1Magic b) {
a.X = a.X + b.X;
return a;
}
}
Code tôi sử dụng để benchmark những được như sau:
class Program {
static void Main(string[] args) {
int iterationCount = 1000000000;
var sw = new Stopwatch();
sw.Start();
var total = 0.0f;
for (int i = 0; i < iterationCount; i++) {
var v = (float) i;
total = total + v;
}
sw.Stop();
Console.WriteLine("Float time was {0} for {1} iterations.", sw.Elapsed, iterationCount);
Console.WriteLine("total = {0}", total);
sw.Reset();
sw.Start();
var totalV = new Vector1(0.0f);
for (int i = 0; i < iterationCount; i++) {
var v = new Vector1(i);
totalV += v;
}
sw.Stop();
Console.WriteLine("Vector1 time was {0} for {1} iterations.", sw.Elapsed, iterationCount);
Console.WriteLine("totalV = {0}", totalV);
sw.Reset();
sw.Start();
var totalVm = new Vector1Magic(0.0f);
for (int i = 0; i < iterationCount; i++) {
var vm = new Vector1Magic(i);
totalVm += vm;
}
sw.Stop();
Console.WriteLine("Vector1Magic time was {0} for {1} iterations.", sw.Elapsed, iterationCount);
Console.WriteLine("totalVm = {0}", totalVm);
Console.Read();
}
}
với những kết quả benchmark:
Float time was 00:00:02.2444910 for 1000000000 iterations.
Vector1 time was 00:00:04.4490656 for 1000000000 iterations.
Vector1Magic time was 00:00:02.2262701 for 1000000000 iterations.
thiết lập trình biên dịch/môi trường: Hệ điều hành: Windows 10 64 bit toolchain: VS2017 Khung: Net 4.6.2 Target: Bất kỳ CPU thích 32 bit
Nếu 64 bit được thiết lập như là mục tiêu, kết quả của chúng tôi được dự kiến được, nhưng còn tồi tệ hơn những gì chúng ta thấy với Vector1Magic trên mục tiêu 32 bit đáng kể:
Float time was 00:00:00.6800014 for 1000000000 iterations.
Vector1 time was 00:00:04.4572642 for 1000000000 iterations.
Vector1Magic time was 00:00:05.7806399 for 1000000000 iterations.
Đối với các trình thuật sĩ sản, tôi đã bao gồm một bãi chứa của IL đây: https://pastebin.com/sz2QLGEx
Điều tra thêm cho thấy rằng điều này có vẻ là cụ thể đối với thời gian chạy Windows, vì trình biên dịch đơn âm tạo ra cùng một IL.
Trên thời gian chạy đơn, cả hai biến thể cấu trúc có hiệu suất gần gấp 2 lần so với phao thô. Điều này hơi khác một chút so với hiệu suất mà chúng ta thấy trên .Net.
Điều gì đang xảy ra ở đây?
* Lưu ý câu hỏi này ban đầu bao gồm quy trình điểm chuẩn không hoàn chỉnh (Cảm ơn Max Payne đã chỉ ra điều này) và đã được cập nhật để phản ánh chính xác hơn thời gian.
Im đoán điều này là do các cấu trúc bao bì bây giờ có sự liên kết bộ nhớ tốt hơn. –
Bạn nên thêm một lần lặp lại để loại trừ nhiễu có thể xảy ra khỏi JIT hoặc xử lý một lần khác. – PetSerAl
Nếu tôi chuyển sang 64 bit, tôi sẽ có hiệu suất kém hơn đối với vectơ "ma thuật" của bạn. – Adrian