我对C ++编程世界很陌生,很抱歉我的问题:
我得到了一个存储在主存储器(1-D阵列)中的大块数据,我需要经常访问一些数据,我的方法是:
float *x=new float[20];//array to store x;
int *indlistforx=new int[20];//array to store the index of x;
float *databank=new float[100000000];//a huge array to store data
/... fill data to databank.../
for (int i=0;i<N;i++)//where N is a very large number;
{
/... write index to indlistforx.../
getdatafromdatabank(x, indlistforx, databank);
//Based on the index provided by indlistforx, read data from databank then pass them to x
/...do something with x.../
};
是否有任何有效/快速的方法来访问这些数据(x的索引未对齐,并且无法对齐)?
非常感谢提前!
答案 0 :(得分:3)
你还没有真正展示你是如何访问你的数据库的,所以这些都非常具有推测性:
是indlistforx
数据库中20个索引的列表,所以你要进行20次随机访问?
20个指数的不同群体跳了多少?他们可以重叠吗?
您可以在更高级别重新排序访问以获得更好的缓存行为:更多顺序,更好的空间或时间参考位置?
indlistforx
请求的级别如果没有看到所有代码(或代表性的样本,我甚至理解这可能太大了),很难再详细介绍。
但是,有一种可能有用的通用技术......它也可能是如此重量级,以至于实施成本超过了节省。
getfromdatabank
返回未来/承诺/无论如何,而不是同步完成(或者20个未来的向量,如果那不是太精细)这只有在额外的同步开销由提高的读取性能支配的情况下才有效,并且如果您可以并行地运行许多查询。
答案 1 :(得分:2)
由于需要初始化一个浮点数,你真的应该使用一个std :: vector&lt;&gt;,它不会慢,构造和填充如下:
std::vector< float > databank( 100000000, 0.0f );
加速有几种选择:
1)如果有一个相当大的密钥(索引)重用,那么你可以使用某种缓存或记忆策略。 有关示例,请参阅http://www.boost.org/doc/libs/1_51_0/libs/flyweight/doc/index.html。
2)您可以使用say std :: async()将处理拆分为多个线程。
3)确保您的编译器已启用simd指令(在x86上为sse)并正在使用它们。如果不使用编译器内在函数强制使用simd。这将使近4倍的改善。
答案 2 :(得分:1)
问题不在于您如何代表databank
。问题是你如何使用它。在短时间内随机访问广泛分离的databank
部分会破坏您的表现。 getdatafromdatabank(x, indlistforx, databank)
indlistforx
indlistforx
几乎可以保证性能不佳。由databank
启用的随机访问会带来显着的性能损失。如果随机访问绝对必要,因为使用databank
的算法如何工作,那只是你必须支付的价格。
如果您可以修改算法,以便在getdatafromdatabank
中访问连续的内存块,您将获得更好的性能。更改x[0]
,以便仅指定第一个索引(要加载到x
的元素的索引)而不是数组20索引。
是否有x
大小为20的原因?如果您几乎无法将输出databank
数组和x
的相关块保留在1级缓存中,您将获得最佳性能。如果{{1}}的大小超出此最佳大小,性能将开始降低,并且可能会显着降低。