在這個項目中我需要創建一個巨大的數組(希望我能創造一個大如〜7.13e + 17,但這一目標仍然高達遙遙領先。)
那調用創建一個專用結構,一個la digital tree(或b-tree),鍵是索引,以避免執行大量分配。
大量分配和特別是重新分配可能會導致不必要的memory fragmentation。如果將大數組分成更小的塊,那麼不僅數組擴展變得容易,而且稀疏數組的呈現變得可能。
N.B. ~7.13e+17
大約有60位長。你甚至有硬件可以支持那麼多的RAM嗎?這並不是說我密切關注着行業,但是我簡要地聽說過使用58位地址總線的NUMA拱形結構 - 但沒有任何關於60位拱形結構的東西。
數組內的每個單元格可以包含三個值之一:0,1,2.2。
如果單元格可能只包含3個值(2.2可以表示爲2),使其成爲2位信息。這意味着您可以將數值打包成uint32_t
32值。
您可以嘗試找到一些現有的數字樹實現(或自己推出)並將其用作索引的關鍵高位。原始索引的剩餘位是樹葉的索引,它將是一個具有打包值的數組。爲了舉例說明代替特里結構的使用std::map
,未測試:
enum {
LS_BITS = 16,
MS_BITS = 64-LS_BITS
};
enum {
VALUE_BITS = 2,
VALUE_MASK = ((1<<VALUE_BITS)-1)
};
// this represents an array of `1<<LS_BITS` values
struct leaf_node {
uint64_t packed_data[ ((1<<LS_BITS)*VALUE_BITS)/(sizeof(uint64_t)*8) ];
};
// that should be a trie, to provide faster look-up
typedef std::map< uint64_t, leaf_node > big_array_type;
void
big_array_set_value(big_array_type &b, uint64_t index, uint64_t value)
{
leaf_node &n = b[index >> LS_BITS];
uint64_t li = index & ((1<<LS_BITS)-1);
li *= VALUE_BITS; // convert into bit offset
uint64_t &x = n.packed_data[ li/(sizeof(uint64_t)*8) ];
li %= (sizeof(uint64_t)*8);
x = (x & (VALUE_MASK<<li)) | (value << li);
}
int
big_array_get_value(big_array_type &b, uint64_t index, uint64_t value)
{
leaf_node &n = b[index >> LS_BITS];
uint64_t li = index & ((1<<LS_BITS)-1);
li *= VALUE_BITS; // convert into bit offset
uint64_t &x = n.packed_data[ li/(sizeof(uint64_t)*8) ];
li %= (sizeof(uint64_t)*8);
return (x >> li) & VALUE_MASK;
}
這樣一個靜止廢物的信息比特0.5自存儲爲2個比特什麼允許4個值,但只有3被使用。這也可以得到改善,但是訪問性能成本要高得多。
你是否擁有一家記憶工廠? – Duck 2010-09-12 17:30:05
您可以用兩位表示0,1,2,因此每個字節可以存儲4個值。做一個快速的劃分,每個字節7.13e17個項目/ 4個項目給出〜162,117 TB的數據。這是非常不切實際的,我認爲你的第一步*是設計一種完全不同的方法。 – 2010-09-12 17:36:11
我編輯了我的主帖,以良好的方式回答您的評論。 – Urielnam 2010-09-12 17:48:39