vector变量在Intel sgx的enclave中可以占用多少内存(MB)?

How much memory(MB) can the vector variable occupy in enclave of Intel sgx?

我想在 sgx 飞地中迁移 PageRank 算法。该算法使用vector来保存边关系和矩阵。

vector<size_t> num_outgoing; // number of outgoing links per column
vector< vector<size_t> > rows; // the rowns of the hyperlink matrix
map<string, size_t> nodes_to_idx; // mapping from string node IDs to numeric
map<size_t, string> idx_to_nodes; // mapping from numeric node IDs to string
vector<double> pr; // the pagerank table

应用程序 运行 在存储少于 9000 个边时运行良好。一旦增加到 10000 个边或更多,应用程序就会崩溃,并抛出未处理的异常enter image description here .我也在 enclave 之外 运行 相同的代码,当它存储 90000 个边缘时它 运行 很好。

通过调试,我发现应用程序在以下地方失败。

if (rows.size() <= max_dim) {
    max_dim = max_dim + 1;
    rows.resize(max_dim);
    if (num_outgoing.size() <= max_dim) {
        num_outgoing.resize(max_dim);
    }
}

但是,变量'rows'一旦拥有13896个元素就不能再变大了。我很困惑 'rows' 只占用大约 300kb 而 'num_outgoing' 只占用大约 100kb。它远远小于允许的大小。飞地应用程序总共有 128MB space。

我的飞地配置文件如下所示。我尝试更改 StackMaxSize 的值,但是,它似乎没有用。

<EnclaveConfiguration>
    <ProdID>0</ProdID>
    <ISVSVN>0</ISVSVN>
    <StackMaxSize>0x400000</StackMaxSize>
    <HeapMaxSize>0x100000</HeapMaxSize>
    <TCSNum>1</TCSNum>
    <TCSPolicy>1</TCSPolicy>
    <DisableDebug>0</DisableDebug>
    <MiscSelect>0</MiscSelect>
    <MiscMask>0xFFFFFFFF</MiscMask>
    <EnableKSS>0</EnableKSS>
    <ISVEXTPRODID_H>0</ISVEXTPRODID_H>
    <ISVEXTPRODID_L>0</ISVEXTPRODID_L>
    <ISVFAMILYID_H>0</ISVFAMILYID_H>
    <ISVFAMILYID_L>0</ISVFAMILYID_L>
</EnclaveConfiguration>

输入边的格式如下图所示。第一个数字是“from”节点,第二个数字是“to”节点

1 0
2 0
3 1
4 3
5 4
6 0
7 1
8 0
9 1
10 0

我想知道如何配置 enclave 以使其允许更大的向量变量? win10和ubuntu.

都存在这个问题

SGX CPU(在 Icelake 之前)的 EPC 有限,对于像 Skylake 这样的 CPU,这是 128M,但您也可以使用 Xeon E-2200 获得 256M。这并不意味着您的应用程序不能使用更多内存,它只是意味着硬件加速内存范围是有限的。不适合 EPC 的页面被交换到非 EPC 内存(以相当大的性能成本),但是这仅在 linux 驱动程序中实现。

因此,您可以将 enclave 堆设置为更大的值,例如 2G。你会看到启动时间变慢(2G 必须完全初始化),如果你的计算内存访问模式分散在 2G 范围内,那么你会看到性能极度下降。因此,请尝试将您的访问模式保持在本地,使用 sequential/scanning 之类的操作等,这是缓存友好计算的通常注意事项。

关于您的实际问题,可能是您 运行 超出了分配的堆,而该向量恰好是“最后一根稻草”。请记住,堆不仅必须包含这些数据结构,还必须包含代码本身。如果您正在解析来自某种序列化格式的输入,那么序列化字节可能仍保留在内存中,如果您有其他状态,那么也使用内存,可能有许多无关使用的来源。如果您使用的是英特尔 SDK,那么我建议您在模拟模式下进行编译,或者只是 link 您的应用程序进入非 SGX ELF 并使用常用的内存调试工具来跟踪内存使用情况。

你似乎 运行 内存不足。使用 StackMaxSizeHeapMaxSize 在配置文件中设置内存限制(堆栈和堆)(有关详细信息,请参阅 Developer Reference)。 EPC 的大小(128MB 或 256MB)与它无关。在这里,您不受 EPC 大小的限制,而是受堆和堆栈的限制。

增加堆栈大小不会改变任何东西,因为动态分配的内存驻留在堆上。反过来,您应该查看最大堆大小。目前,您已将其设置为 0x100000 (=1MB),这很快就会被您的数据用完。尝试增加它,看看是否可以容纳更大的向量。

我认为在 Windows 上,您的 enclave 必须完全适合 EPC,但在 Linux 上,您可以创建数十 GB 的 enclave。请注意,一旦您的 (Linux) enclave 内存使用量超过 ~90 MB,您将开始注意到 EPC 分页,随之而来的是性能的巨大下降。

虽然其他答案完全正确,但英特尔最近将内存限制提高到了 1Tb,请参阅 here 了解更多信息。