2014-04-07 5 views
45

Lesen Sie diese fascinating article über die 20x-200x Verlangsamungen, die Sie auf Intel-CPUs mit denormalized floats (Fließkommazahlen sehr nahe bei 0) bekommen können.Wie werden denormalisierte Floats in C# behandelt?

Es gibt eine Option mit SSE, um diese auf 0 zu runden, wodurch die Leistung wiederhergestellt wird, wenn solche Gleitkommawerte auftreten.

Wie gehen C# -Apps damit um? Gibt es eine Option zum Aktivieren/Deaktivieren _MM_FLUSH_ZERO?

+23

Ich denke nicht, dass dies eine dumme technische Frage ist. – user1717828

Antwort

43

Es gibt keine solche Option.

Das FPU-Steuerwort in einer C# -App wird beim Start von der CLR initialisiert. Das Ändern ist keine Option, die vom Framework bereitgestellt wird. Selbst wenn Sie versuchen, es zu ändern, indem Sie _control87_2() pinvokieren, dann wird es nicht lange dauern; Jede Ausnahme bewirkt, dass das Steuerwort durch die Implementierung der Ausnahmebehandlung innerhalb der CLR erneut zurückgesetzt wird. Was geschrieben wurde, um sich mit einem anderen Aspekt des FPU-Steuerwortes zu befassen, erlaubt es, Gleitkommaausnahmen zu demaskieren. Es ist auch schädlich für jeden anderen verwalteten Code, der nicht erwartet, dass der globale Status so geändert wird.

Keine direkte Kontrolle über die Hardware ist eine implizite Einschränkung, wenn Sie Code in einer virtuellen Maschine ausführen. Nicht, dass dies in nativem Code überhaupt leicht zu tun ist, Bibliotheken neigen dazu, sich schlecht zu benehmen, wenn sie auch erwarten, dass die FPU die Standardinitialisierung hat. Insbesondere ein Problem mit den Ausnahmenmaskierungsflags, DLLs, die mit Borland-Tools erstellt wurden, haben ein Talent dafür, Exceptions einzuschalten, was dazu führt, dass anderer Code fehlschlägt, der nicht für die Behandlung einer solchen Ausnahme geschrieben wurde. Ein extrem hässliches Problem zu lösen, das FPU-Steuerwort ist die schlechteste mögliche globale Variable, die Sie sich vorstellen können.

Dies belastet Sie, damit Ihre Gleitkommaberechnungen nicht so drunter und drüber gehen. Die Berechnung mit Denormalen liefert fast immer unsinnige Ergebnisse, wenn nicht von den radikal kleinen Werten, dann zumindest vom schnellen Verlust signifikanter Ziffern. Es ist Ihnen überlassen, Werte kleiner als 2.2E-308 auf 0 abzuschneiden. Ja, nicht sehr praktisch. Vielleicht ist es okay für ein Programm, Unsinn Ergebnisse ein bisschen langsamer als normal zu liefern :)

+0

Während ich Ihre Antwort vollständig akzeptiere, dass es nicht getan werden kann, stelle ich die Trivialisierung des Problems in Frage. Das Abschneiden von Doppelten kann selten sein; Aber es ist sehr einfach, Singles bei der Audioverarbeitung zu denormalisieren (z. B. digitale Filter, Verzögerungsleitungen usw.). Angesichts der Tatsache, dass der Performance-Hit auf der x86-Architektur entsetzlich ist, wäre es sehr schön, die Auslösung von Denorm-Exceptions zu verlangen. Skalare haben Operationen überprüft. Warum schwebt nicht auch? –

+1

Pinvoking _control87_2() ist einfach kein Problem, wenn der Code so lokalisiert ist. Verwenden Sie _DN_FLUSH, vergessen Sie nicht, es zurückzusetzen. –

Verwandte Themen