Net 4.6 RC x64 là hai lần chậm như x86 (phát hành phiên bản):.NET 4.6 RC x64 là hai lần chậm như x86 (phát hành phiên bản)
Hãy xem xét đoạn mã này:
class SpectralNorm
{
public static void Main(String[] args)
{
int n = 5500;
if (args.Length > 0) n = Int32.Parse(args[0]);
var spec = new SpectralNorm();
var watch = Stopwatch.StartNew();
var res = spec.Approximate(n);
Console.WriteLine("{0:f9} -- {1}", res, watch.Elapsed.TotalMilliseconds);
}
double Approximate(int n)
{
// create unit vector
double[] u = new double[n];
for (int i = 0; i < n; i++) u[i] = 1;
// 20 steps of the power method
double[] v = new double[n];
for (int i = 0; i < n; i++) v[i] = 0;
for (int i = 0; i < 10; i++)
{
MultiplyAtAv(n, u, v);
MultiplyAtAv(n, v, u);
}
// B=AtA A multiplied by A transposed
// v.Bv /(v.v) eigenvalue of v
double vBv = 0, vv = 0;
for (int i = 0; i < n; i++)
{
vBv += u[i] * v[i];
vv += v[i] * v[i];
}
return Math.Sqrt(vBv/vv);
}
/* return element i,j of infinite matrix A */
double A(int i, int j)
{
return 1.0/((i + j) * (i + j + 1)/2 + i + 1);
}
/* multiply vector v by matrix A */
void MultiplyAv(int n, double[] v, double[] Av)
{
for (int i = 0; i < n; i++)
{
Av[i] = 0;
for (int j = 0; j < n; j++) Av[i] += A(i, j) * v[j];
}
}
/* multiply vector v by matrix A transposed */
void MultiplyAtv(int n, double[] v, double[] Atv)
{
for (int i = 0; i < n; i++)
{
Atv[i] = 0;
for (int j = 0; j < n; j++) Atv[i] += A(j, i) * v[j];
}
}
/* multiply vector v by matrix A and then by matrix A transposed */
void MultiplyAtAv(int n, double[] v, double[] AtAv)
{
double[] u = new double[n];
MultiplyAv(n, v, u);
MultiplyAtv(n, u, AtAv);
}
}
Trên phiên bản phát hành máy x86 của tôi mất 4,5 giây để hoàn thành, trong khi x64 mất 9,5 giây. Có bất kỳ cờ/cài đặt cụ thể nào cần thiết cho x64 không?
CẬP NHẬT
Nó chỉ ra rằng RyuJIT có một vai trò trong vấn đề này. Nếu useLegacyJit
được bật trong app.config, kết quả sẽ khác và lần này x64 nhanh hơn.
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.6"/>
</startup>
<runtime>
<useLegacyJit enabled="1" />
</runtime>
</configuration>
CẬP NHẬT
Bây giờ vấn đề này đã được báo cáo cho đội CLR coreclr, issue 993
Tôi không quen thuộc với định mức quang phổ, và đó là một số tiền hợp lý của mã để xem xét. Bạn có thể cho chúng tôi một bản tóm tắt về những gì đang làm - hàng trăm hoặc hàng ngàn phép toán ma trận của các ma trận hai điểm nổi lớn với các căn bậc hai và các bộ phận trong đó ở đâu đó? Bạn có thể cấu hình này trong cả hai, bạn có thể nhìn vào bộ tạo ra cho bất kỳ bi quan rõ ràng? – Rup
Bạn có đang chạy bản phát hành bản phát hành và không chạy nó trong trình gỡ lỗi không? –
Nó có giá trị chạy nó một vài lần trong một vòng lặp 'for' và giảm giá vài lần lặp đầu tiên kể từ khi trình biên dịch JIT cần phải làm việc phép thuật của nó lần đầu tiên. –