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

Fast percentile in C++ - speed more important than precision

本文关键字:精度 速度 百分比 C++      更新时间:2023-10-16

这是C++中Fast百分位数的后续操作

我有一个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分钟。由于问题的性质,这1500万不太可能在未来大幅降低,只会增加。使用过"VTune分析器"后,有人告诉我,除了最后一行(generatedVal += ...)外,其余的一行生成80%的运行时。我的问题是,我为什么以及如何才能做到这一点。

我尝试过的东西:

1/去掉(dIdx - dFloor)部分,看看二重差和乘法是否是罪魁祸首——运行时下降了几个百分点

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

3/尝试使用16天(而不是365天)来查看是否是缓存未命中拖累了我的性能——而不是的微小变化

4/尝试使用浮动而不是双重-无更改

5/使用不同的/fp:-无更改进行编译

6/编译为x64-对双lt;->有影响ulong转换,但有问题的线路不受影响

我愿意牺牲的是分辨率——如果速度增益很大,我不在乎generatedVal最终是100010.1还是100020.0。

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

也许您可以将分段线性函数转换为其值的分段线性"直方图"。您正在采样的数字似乎是该直方图中365个样本的总和。你正在做的是从该直方图的365个样本的总和中进行采样,这不是一种特别快速的方法。

你可以尝试计算傅立叶(或小波或类似的)变换,只保留前几项,将其提高到365次方,然后计算逆变换。你最终不会得到概率分布,但使用这种技术,0以下或1以上的质量不应该"太多",总质量也不应该与1"太不同"。(我不知道你的数据是什么样子的;由于数学上的原因,这种技术可能不可行。)