我已經將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