MatlabとC++の間のバニラコールオプションのMonte Carlo価格設定アルゴリズムの速度を比較しています。高速化は行列乗算によるものではなく(高速に実行されるドットプロダクトのみであるため)、非常に効率的なガウス乱数ジェネレータによるものと思われるため、これはWhy is MATLAB so fast in matrix multiplication?と同じではありません。コードがベクトル化されており、なぜMatlabはC++よりも11倍高速です
function [ value ] = OptionMCValue(yearsToExpiry, spot, strike, riskFreeRate, dividendYield, volatility, numPaths )
sd = volatility*sqrt(yearsToExpiry);
sAdjusted = spot * exp((riskFreeRate - dividendYield - 0.5*volatility*volatility) * yearsToExpiry);
g = randn(1,numPaths);
sT = sAdjusted * exp(g * sd);
values = max(sT-strike,0);`
value = mean(values);
value = value * exp(-riskFreeRate * yearsToExpiry);
end
strike = 100.0;
yearsToExpiry = 2.16563;
spot = 100.0;
volatility = 0.20;
dividendYield = 0.03;
riskFreeRate = 0.05;
oneMillion = 1000000;
numPaths = 10*oneMillion;
tic
value = OptionMCValue(yearsToExpiry, spot, strike, riskFreeRate, dividendYield, volatility, numPaths );
toc
を次のように私は千万のパスでこれを実行すると、私は
Elapsed time is 0.359304 seconds.
12.8311
を取得するには、次のようにコードが見えMATLABで
今私はVS2013のC++で同じことを行います
私のコードはOptionMCクラスであると私はVisual Studioで速度を最適化するために、最適化オプションを設定している
double GaussianRVByBoxMuller()
{
double result;
double x; double y;;
double w;
do
{
x = 2.0*rand()/static_cast<double>(RAND_MAX)-1;
y = 2.0*rand()/static_cast<double>(RAND_MAX)-1;
w = x*x + y*y;
} while (w >= 1.0);
w = sqrt(-2.0 * log(w)/w);
result = x*w;
return result;
}
を次のようにBMコードがある
double OptionMC::value(double yearsToExpiry,
double spot,
double riskFreeRate,
double dividendYield,
double volatility,
unsigned long numPaths)
{
double sd = volatility*sqrt(yearsToExpiry);
double sAdjusted = spot * exp((riskFreeRate - dividendYield - 0.5*volatility*volatility) * yearsToExpiry);
double value = 0.0;
double g, sT;
for (unsigned long i = 0; i < numPaths; i++)
{
g = GaussianRVByBoxMuller();
sT = sAdjusted * exp(g * sd);
value += Max(sT - m_strike, 0.0);
}
value = value * exp(-riskFreeRate * yearsToExpiry);
value /= (double) numPaths;
return value;
}
を以下のようです。
10mパスの場合、4.124秒かかります。
これはMatlabの11倍です。
誰でもその違いを説明できますか?
EDIT:さらなるテストでは、スローダウンはGaussianRVByBoxMullerの呼び出しであるようです。 Matlabは非常に効率的な実装、つまりZigguratメソッドを持っているようです。ここでBMは2つのRVを生成するので、ここでは最適ではないことに注意してください。私は1だけを使用します。これを固定すると2倍のスピードアップが得られます。
C++バージョンはMATLABバージョンのようにベクトル化されていますか? – NathanOliver
Matlabで使用される最適化は、C++コンパイラがコードに対して行うのと同じではありません。 –
.netフレームワークを使用しているかどうかを確認してください。それが影響を与えるかどうかはわかりません。 – xvan