简体   繁体   English

存储大量编译时间常数数据

[英]Storing large amounts of compile time constant data

I hope that this question hasn't been asked before, but I couldn't find any answer after googling for an hour.我希望这个问题以前没有被问过,但是在谷歌搜索一个小时后我找不到任何答案。

I have the following problem: I do numerical mathematics and I have about 40 MB of doubles in the form of certain matrices that are compile time constants.我有以下问题:我做数值数学,我有大约 40 MB 的doubles数,它们以某些矩阵的形式出现,这些矩阵是编译时间常数。 I very frequently use these matrices throughout my program.我在整个程序中经常使用这些矩阵。 The creation of these matrices takes a week of computation, so I do not want to compute them on the fly but use precomputed values.这些矩阵的创建需要一周的计算时间,所以我不想即时计算它们,而是使用预先计算的值。

What is the best way of doing this in a portable manner?以便携式方式执行此操作的最佳方法是什么? Right now I have some very large CPP-files, in which I create dynamically allocated matrices with the constants as initialiser lists.现在我有一些非常大的 CPP 文件,我在其中创建动态分配的矩阵,其中常量作为初始化列表。 Something along the lines:类似的东西:

data.cpp:数据.cpp:

namespace // Anonymous
{

// math::matrix uses dynamic memory internally
const math::matrix K { 3.1337e2, 3.1415926e00, /* a couple of hundred-thousand numbers */ };

}

const math::matrix& get_K() { return K; }

data.h数据.h

const math::matrix& get_K();

I am not sure if this can cause problems with too much data on the stack, due to the initialiser list.由于初始化列表,我不确定这是否会导致堆栈上数据过多的问题。 Or if this can crash some compilers.或者,如果这会使某些编译器崩溃。 Or if this is the right way to go about things.或者如果这是 go 关于事情的正确方法。 It does seem to be working though.它似乎确实有效。

I also thought about loading the matrices at program startup from an external file, but that also seems messy to me.我还考虑过在程序启动时从外部文件加载矩阵,但这对我来说似乎也很混乱。

Thank you very much in advance!非常感谢您!

I am not sure if this can cause problems with too much data on the stack, due to the initialiser list.由于初始化列表,我不确定这是否会导致堆栈上数据过多的问题。

There should not be a problem assuming it has static storage with non-dynamic initialisation.假设它具有非动态初始化的 static 存储,应该没有问题。 Which should be the case if math::matrix is an aggregate.如果math::matrix是一个聚合应该是这种情况。

Given that the values will be compile time constant, you might consider defining them in a header, so that all translation units can take advantage of them at compile time.鉴于这些值将是编译时常量,您可以考虑在 header 中定义它们,以便所有翻译单元可以在编译时利用它们。 How beneficial that would be depends on how the values are used.这将如何有益取决于如何使用这些值。

I also thought about loading the matrices at program startup from an external file我还考虑过在程序启动时从外部文件加载矩阵

The benefit of this approach is the added flexibility that you gain because you would not need to recompile the program when you change the data.这种方法的好处是您获得了额外的灵活性,因为您在更改数据时不需要重新编译程序。 This is particularly useful if the program is expensive to compile.如果程序的编译成本很高,这将特别有用。

A slightly cleaner approach:一个稍微干净的方法:

// math::matrix uses dynamic memory internally
const math::matrix K { 
   #include "matrix_initial_values.h"
};

And, in the included header,并且,在随附的 header 中,

3.1337e2, 3.1415926e00, 1,2,3,4,5e6, 7.0,...

Considering your comment of "A few hundred thousand" float values: 1M double values takes 8,000,000 bytes, or about 7.6MB.考虑到您对“几十万”浮点值的评论:1M double精度值需要 8,000,000 字节,或大约 7.6MB。 That's not going to blow the stack.这不会破坏堆栈。 Win64 has a max stack size of 1GB, so you'd have to go really, really nuts, and that's assuming that these values are actually placed on the stack, which they should not be given that it's const . Win64 的最大堆栈大小为 1GB,所以你必须 go 真的,真的很疯狂,这是假设这些值实际上是放在堆栈上的,它们不应该被认为是const

This is probably implementation-specific, but a large block of literals is typically stored as a big chunk of code-space data that's loaded directly into the process' memory space.这可能是特定于实现的,但是一大块文字通常存储为一大块代码空间数据,这些数据直接加载到进程的 memory 空间中。 The identifier ( K ) is really just a label for that data.标识符 ( K ) 实际上只是该数据的 label。 It doesn't exist on the stack or the heap anymore than code does.它不再存在于堆栈或堆中,而不是代码。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM