C ++中的快速百分位数 - 速度比精度更重要

时间:2013-12-14 21:37:00

标签: c++ performance

这是Fast percentile in C++

的后续行动

我有一个365个每日现金流量的排序数组(xDailyCashflowsDistro),我随机抽样365次以获得每年的现金流量。生成由

执行
1/ picking a random probability in the [0,1] interval
2/ converting this probability to an index in the [0,364] interval
3/ determining what daily cashflow corresponds to this probability by using the index and some linear aproximation.

并总结365生成的每日现金流量。按照前面提到的线程,我的代码预先计算了每日现金流量的差异(xDailyCashflowDiffs

xDailyCashflowDiffs[i] = xDailyCashflowsDistro[i+1] - xDailyCashflowsDistro[i]

因此整个代码看起来像

double _dIdxConverter = ((double)(365 - 1)) / (double)(RAND_MAX - 1);

for (  unsigned int xIdx = 0; xIdx < _xCount; xIdx++ )
{
    double generatedVal = 0.0;
    for (  unsigned int xDayIdx = 0; xDayIdx < 365; xDayIdx ++ )
    {
         double dIdx    = (double)fastRand()* _dIdxConverter;       
         long   iIdx1   = (unsigned long)dIdx;                          
         double dFloor  = (double)iIdx1;                                

        generatedVal += xDailyCashflowsDistro[iIdx1] + xDailyCashflowDiffs[iIdx1] *(dIdx  - dFloor);
    }
    results.push_back(generatedVal) ;
}

_xCount(模拟次数)为1K +,通常为10K。

问题:   此刻模拟正在执行15M次(当写入第一个线程时为100K),在3.4GHz机器上需要大约10分钟。由于问题的性质,这个15M不太可能在未来显着降低,只会增加。使用过VTune Analyzer之后,我被告知最后一行(generatedVal += ...)会产生80%的运行时间。我的问题是为什么以及如何使用它。

我尝试过的事情:

1 /摆脱(dIdx - dFloor)部分,看看双重差异和乘法是否是罪魁祸首 - 运行时间下降了几个百分点

2 /将xDailyCashflowsDistroxDailyCashflowDiffs声明为__restict,以防止编译器认为它们相互依赖 - 无变化

3 /尝试使用16天(而不是365)来查看是否存在拖动我的性能的缓存未命中 - 而不是轻微的更改

4 /尝试使用花车而不是双打 - 没有变化

5 /用不同的/ fp编译: - 没有变化

6 /编译为x64 - 对double&lt; - &gt;有影响。 ulong转换,但相关的行不受影响

我愿意牺牲的是解决方案 - 如果速度增益很大,我不关心generatedVal最后是100010.1还是100020.0。

修改 每日/每年现金流量与整个投资组合相关。我可以按portflio大小划分所有每日现金流量,因此(99.99%置信水平)确保每日现金流/ pflio_size不会超出[-1000,+ 1000]区间。但在这种情况下,我需要精确到百分之一。

1 个答案:

答案 0 :(得分:0)

也许您可以将分段线性函数转换为其值的分段线性“直方图”。您采样的数字似乎是该直方图中365个样本的总和。您正在做的是从该直方图中采集365个样本的总和,这是一种非常快速的方法。

您可以尝试计算傅立叶(或小波或类似)变换,仅保留前几个项,将其提升到365次幂,并计算逆变换。最后你不会得到概率分布,但是不应该有“太多”质量低于0或高于1,并且总质量不应该与这种技术的“太大不同”。 (我不知道你的数据是什么样的;出于好的数学原因,这种技术可能不可行。)