Ich habe einen Teil von Boost - die ibeta_inv-Funktion - in eine .Net 64-Bit-Assembly kompiliert und es funktionierte großartig, bis ich anfing, es aus mehreren Threads aufzurufen. Dann gibt es gelegentlich falsche Ergebnisse zurück.Boost Mathematik (ibeta_inv Funktion) nicht thread sicher?
I erfüllt es mit diesem Code (C++/CLI):
// Boost.h
#pragma once
#include <boost/math/special_functions/beta.hpp>
using namespace boost::math;
namespace Boost {
public ref class BoostMath
{
public:
double static InverseIncompleteBeta(double a, double b, double x)
{
return ibeta_inv(a,b,x);
}
};
}
Hat jemand schon einmal ausprobiert?
Ich habe nicht versucht, dies außerhalb .Net, so dass ich nicht weiß, ob dies die Ursache ist, aber ich sehe wirklich nicht warum, da es funktioniert super single threaded.
Verbrauch (C#):
private void calcBoost(List<Val> vals)
{
//gives WRONG results (sometimes):
vals.AsParallel().ForAll(v => v.BoostResult = BoostMath.InverseIncompleteBeta(v.A, v.B, v.X));
//gives CORRECT results:
vals.ForEach(v => v.BoostResult = BoostMath.InverseIncompleteBeta(v.A, v.B, v.X));
}
UPDATE: Wie unten in meinen Kommentaren zu sehen - ich bin nicht sicher, überhaupt nicht mehr, dass dies ein Boost-Problem. Vielleicht ist es ein seltsamer PLinq zu C++/CLI Bug ??? Ich bin geblufft und werde später mit mehr Fakten zurückkehren.
Dokumentation sagt ganze boost.math sollte threadsicher sein, solange Sie eingebaute Fließkommatypen verwenden (was, wie ich sehe, Sie tun). Vielleicht sollten Sie einen Fehler einreichen? http://www.boost.org/doc/libs/release/libs/math/doc/sf_and_dist/html/math_toolkit/main_overview/threads.html – stanwise
Wenn nichts anderes auftaucht, kann ich es in einem nativen C++ ausprobieren App und sehen, ob das Problem bestehen bleibt. Wenn dies der Fall ist, kann ein Fehlerbericht die einzige Sache sein, da ich nichts im Quellcode finden kann. Schade, aber ... es läuft doppelt so schnell wie unsere aktuelle Implementierung der inversen unvollständigen Beta-Funktion. –
Interessant!Zwei Gedanken kommen in den Sinn: (1) Treble-Check, den Sie Boost im Multithread-Modus gebaut haben (aktuelle Versionen machen immer noch die Unterscheidung), und (2) dieses Zitat aus der Dokumentation @stanwise verknüpft: 'Der Grund für die letztere Einschränkung ist die Notwendigkeit, symbolische Konstanten mit Hilfe von Konstrukten zu initialisieren ... da in diesem Fall die Konstruktoren von T ausgeführt werden müssen, was zu möglichen Wettlaufbedingungen führt. Ich frage mich offen, ob dein Code diesen Wettlaufzustand unerwartet offen legt und ich von ganzem Herzen zurück stanwise, dies als Fehler zu melden. – MrGomez