无法为分区 table 上的一列复合浮点数分配内存
Cannot allocate memory for a column of compound floats on a partitioned table
我的 hdb 中有一个分区 table,其中包含一个包含大量浮点数列表的列(每个元素最多 400 个浮点数)。例如每个元素看起来像
(100.0 1.0 ...)
从行数特别多的日子开始在此列上尝试 select 时,我收到一条错误消息
'./2015.02.07/table/column# Cannot allocate memory
同样的错误来自如下查询:
select column[;0] from table where date=2015.02.07
即使在行数较少的日子里,此查询 returns 列中每个元素的第一个值。
有没有办法在 select 中流式传输此列以减少将整个列保存在内存中一整天的内存需求?
编辑
.Q.ind 在大日子里失败并出现同样的错误。
也就是说我可以使用 2015.02.01 但不能使用 2015.02.02:
.Q.ind[select from table where date=2015.02.01;enlist 1]
很好但是
.Q.ind[select from table where date=2015.02.02;enlist 1]
失败
{0!$[#.Q.pm;p3;(?).]@[x;0;p1[;y;z]]}
'./2015.02.10/table/column2#: Cannot allocate memory
@
.[?]
(+`time`sym`column1`column2!`:./2015.02.02/table;();0b;())
请注意,我使用的是免费的 32 位版本
嵌套列使得以通常方式进行查询变得困难,因为 #
文件也需要加载到内存中(即使使用 [;0]
)
最好的办法是 select 映射日期分区,然后 select 在该块中逐块映射,例如一次一百万行(或给定嵌套浮点数的大小,任何合理的行)。
如果可以牺牲一些小数精度,或许也可以考虑 32 位浮点数。
编辑
所以在评论之后我想最好的方法是用 .Q.ind
一次将每个分区分成多行
我认为这只是自由 32 位内存限制的组合,您的行数可能很大以及(不可避免地)某些东西 必须是从列中检索数据时完全拉入内存,无论是列本身完全拉入(在非嵌套情况下)还是嵌套索引列完全拉入。
要考虑的另一件事是 kdb 使用二次方(伙伴)内存分配。即使今天 table 只比昨天多一行,每列的内存需求也可能翻倍。举个简单的例子:
在免费的 32 位版本 (windows) 中,您可以创建这么多的浮点数,并且它只使用 ~1.07gb 的内存
q)\ts 134217726?1.0
3093 1073741952
但是,如果尝试生成一个额外的浮点数,则会遇到内存限制
q)\ts 134217727?1.0
wsfull
因此,如果您接近 allocatable 二次方的边界,那么即使是一天和下一天之间的差异中的少量行也可能非常重要。
--免责声明--以下是 hacky,仅用于调试!
您实际上可以手动尝试访问嵌套列表中的数据,尽管您仍然可能在这里遇到内存问题。
创建嵌套 table 并展开它
q)tab:([] col1:(101 102 103f;104 105f;106 107 108 109 110f;111 112f))
q)tab
col1
--------------------
101 102 103f
104 105f
106 107 108 109 110f
111 112f
q)
q)`:test/ set tab
`:test/
您可以尝试从嵌套索引文件中读取索引
q)2_first (enlist "j";enlist 8)1:`:test/col1
3 5 10 12
因此,用于拆分完整浮点数列表(col1# 文件)的索引是索引 3、索引 5、10 等等
假设我想要前 3 行
q)myrows:3#2_first (enlist "j";enlist 8)1:`:test/col1
q)myrows
3 5 10
然后我知道我需要 col1# 文件中的前 10 个浮点数,并且需要在索引 3 和 5 处拆分它们。然后我可以读取 col1# 文件部分并正确拆分
q)(0,-1_myrows) cut raze (enlist "f";enlist 8)1:(`$":test/col1#";0;8*last myrows)
101 102 103f
104 105f
106 107 108 109 110f
但这正是 KDB 在幕后所做的事情,所以我怀疑您甚至一开始就无法读取嵌套索引文件。
检查这个 debug/hack 看看你是否可以部分阅读。但显然不是长久之计!
为了让我付出 2 美分,我遇到了类似的错误,但使用的是 64 位实例。
我怀疑内存需要整理碎片,因为它 运行 已经快一年了。
启动实例解决了问题,并释放了大量虚拟内存
我的 hdb 中有一个分区 table,其中包含一个包含大量浮点数列表的列(每个元素最多 400 个浮点数)。例如每个元素看起来像
(100.0 1.0 ...)
从行数特别多的日子开始在此列上尝试 select 时,我收到一条错误消息
'./2015.02.07/table/column# Cannot allocate memory
同样的错误来自如下查询:
select column[;0] from table where date=2015.02.07
即使在行数较少的日子里,此查询 returns 列中每个元素的第一个值。
有没有办法在 select 中流式传输此列以减少将整个列保存在内存中一整天的内存需求?
编辑
.Q.ind 在大日子里失败并出现同样的错误。
也就是说我可以使用 2015.02.01 但不能使用 2015.02.02:
.Q.ind[select from table where date=2015.02.01;enlist 1]
很好但是
.Q.ind[select from table where date=2015.02.02;enlist 1]
失败
{0!$[#.Q.pm;p3;(?).]@[x;0;p1[;y;z]]}
'./2015.02.10/table/column2#: Cannot allocate memory
@
.[?]
(+`time`sym`column1`column2!`:./2015.02.02/table;();0b;())
请注意,我使用的是免费的 32 位版本
嵌套列使得以通常方式进行查询变得困难,因为 #
文件也需要加载到内存中(即使使用 [;0]
)
最好的办法是 select 映射日期分区,然后 select 在该块中逐块映射,例如一次一百万行(或给定嵌套浮点数的大小,任何合理的行)。
如果可以牺牲一些小数精度,或许也可以考虑 32 位浮点数。
编辑
所以在评论之后我想最好的方法是用 .Q.ind
我认为这只是自由 32 位内存限制的组合,您的行数可能很大以及(不可避免地)某些东西 必须是从列中检索数据时完全拉入内存,无论是列本身完全拉入(在非嵌套情况下)还是嵌套索引列完全拉入。
要考虑的另一件事是 kdb 使用二次方(伙伴)内存分配。即使今天 table 只比昨天多一行,每列的内存需求也可能翻倍。举个简单的例子:
在免费的 32 位版本 (windows) 中,您可以创建这么多的浮点数,并且它只使用 ~1.07gb 的内存
q)\ts 134217726?1.0
3093 1073741952
但是,如果尝试生成一个额外的浮点数,则会遇到内存限制
q)\ts 134217727?1.0
wsfull
因此,如果您接近 allocatable 二次方的边界,那么即使是一天和下一天之间的差异中的少量行也可能非常重要。
--免责声明--以下是 hacky,仅用于调试!
您实际上可以手动尝试访问嵌套列表中的数据,尽管您仍然可能在这里遇到内存问题。
创建嵌套 table 并展开它
q)tab:([] col1:(101 102 103f;104 105f;106 107 108 109 110f;111 112f))
q)tab
col1
--------------------
101 102 103f
104 105f
106 107 108 109 110f
111 112f
q)
q)`:test/ set tab
`:test/
您可以尝试从嵌套索引文件中读取索引
q)2_first (enlist "j";enlist 8)1:`:test/col1
3 5 10 12
因此,用于拆分完整浮点数列表(col1# 文件)的索引是索引 3、索引 5、10 等等
假设我想要前 3 行
q)myrows:3#2_first (enlist "j";enlist 8)1:`:test/col1
q)myrows
3 5 10
然后我知道我需要 col1# 文件中的前 10 个浮点数,并且需要在索引 3 和 5 处拆分它们。然后我可以读取 col1# 文件部分并正确拆分
q)(0,-1_myrows) cut raze (enlist "f";enlist 8)1:(`$":test/col1#";0;8*last myrows)
101 102 103f
104 105f
106 107 108 109 110f
但这正是 KDB 在幕后所做的事情,所以我怀疑您甚至一开始就无法读取嵌套索引文件。
检查这个 debug/hack 看看你是否可以部分阅读。但显然不是长久之计!
为了让我付出 2 美分,我遇到了类似的错误,但使用的是 64 位实例。
我怀疑内存需要整理碎片,因为它 运行 已经快一年了。
启动实例解决了问题,并释放了大量虚拟内存