He compilado parte de boost - la función ibeta_inv - en un ensamblado .Net de 64 bits y funcionó muy bien hasta que comencé a llamarlo desde múltiples hilos. Luego, ocasionalmente devuelve resultados incorrectos.Boost math (función ibeta_inv) ¿no es seguro para subprocesos?
Accedí que el uso de este código (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);
}
};
}
Alguien ha probado esto antes?
No he probado esto fuera de .Net, así que no sé si esta es la causa, pero realmente no veo por qué, ya que funciona muy bien.
Uso (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));
}
ACTUALIZACIÓN: Como se puede ver en mis comentarios a continuación - no estoy seguro en todos los más que se trata de un problema Boost. Tal vez es un error raro de PLinq a C++/CLI ??? Estoy descartado y volveré con más hechos más tarde.
La documentación dice que todo boost.math debe ser seguro para subprocesos siempre que uses tipos de punto flotante integrados (que, como veo, lo haces). Tal vez deberías presentar un error? http://www.boost.org/doc/libs/release/libs/math/doc/sf_and_dist/html/math_toolkit/main_overview/threads.html – stanwise
Si no aparece nada más, puedo probarlo en un C++ nativo aplicación y ver si el problema persiste. Si es así, un informe de error puede ser lo único que se debe hacer, ya que no puedo encontrar nada en el código fuente. Aunque es una pena ... funciona dos veces más rápido que nuestra implementación actual de la función beta incompleta inversa. –
¡Interesante!Me vienen a la mente dos pensamientos: (1) la triplicación ha creado impulso en modo multiproceso (las versiones actuales aún distinguen), y (2) esta cita, de la documentación @stanwise vinculada: 'La razón de esta última limitación es la necesidad de inicializar constantes simbólicas usando constructos ... como en este caso hay una necesidad de ejecutar los constructores de T, lo que conduce a posibles condiciones de carrera. "Me pregunto abiertamente si su código expone esta condición de carrera de forma inesperada, y de todo corazón de manera estándar al informar esto como un error. – MrGomez