我已经将boost的一部分 - ibeta_inv函数编译到了一个.Net 64位程序集中,它运行良好,直到我开始从多线程调用它。然后它偶尔返回错误的结果。Boost数学(ibeta_inv函数)不是线程安全的?
我遵守它使用此代码(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);
}
};
}
有没有人尝试过呢?
我没有试过这个.Net,所以我不知道这是不是原因,但我真的不明白为什么,因为它的工作原理很棒单线程。
用法(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:可以看出在下面我的意见 - 我不知道在所有了,这是一个加速的问题。也许这是一些奇怪的PLinq到C++/CLI bug?我很忙,并且会在稍后回复更多的事实。
文档说整个boost.math应该是线程安全的,只要您使用内置的浮点类型(正如我所看到的那样)。也许你应该提交一个bug? http://www.boost.org/doc/libs/release/libs/math/doc/sf_and_dist/html/math_toolkit/main_overview/threads.html – stanwise 2012-03-27 12:08:40
如果没有其他东西出现,我可以在本机C++中尝试应用程序,看看问题是否仍然存在。如果是这样,一个错误报告可能是唯一要做的事情,因为我无法在源代码中找到任何东西。虽然可惜......它的运行速度是我们目前实现的反向不完全测试函数的两倍。 – 2012-03-27 12:12:48
有趣!想到两个想法:(1)三重检查你已经在多线程模式下建立了提升(当前版本仍然有区别),(2)这个引用来自@stanwise linked文档:'后一个限制的原因是需要使用结构来初始化符号常量......因为在这种情况下,需要运行T的构造函数,导致潜在的竞争条件。“我公开怀疑你的代码是否意外地暴露了这种竞争条件,并且我全心全意地回来stanwise报告这是一个错误。 – MrGomez 2012-04-02 22:11:24