netto 4.6 RC 64 è due volte più lento come x86 (versione):.NET 4.6 RC 64 è due volte più lento come x86 (versione di rilascio)
considerare questo pezzo di codice:
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);
}
}
Sulla mia macchina, la versione di rilascio x86 impiega 4,5 secondi per essere completata, mentre la x64 impiega 9,5 secondi. C'è qualche bandiera/impostazione specifica necessaria per x64?
UPDATE
Si scopre che RyuJIT ha un ruolo in questo numero. Se useLegacyJit
è abilitato in app.config, il risultato è diverso e questa volta x64 è più veloce.
<?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>
UPDATE
Ora il problema è stato segnalato al team CLR coreclr, issue 993
Non ho dimestichezza con le norme spettrali, e questa è una discreta quantità di codice da prendere in considerazione. Potresti fornirci un riassunto di ciò che sta facendo - centinaia o migliaia di operazioni con matrici di grandi matrici a virgola mobile con radici quadrate e divisioni anche lì da qualche parte? Puoi profilare questo in entrambi, puoi guardare all'assemblatore generato per eventuali pessimitazioni evidenti? – Rup
Stai eseguendo una versione di rilascio e non la stai eseguendo in un debugger? –
Vale la pena eseguirlo alcune volte in un ciclo 'for' e scartando le prime iterazioni dal momento che il compilatore JIT ha bisogno di eseguire la sua magia la prima volta. –