堆栈的写时复制
Copy-on-write for stacks
如何在大数后缀计算中实现堆栈管理的写时复制技术?
我想针对以下操作优化我的系统:
duplicate top of stack
swap the two top elements
copy the second element on stack to the top
rotate the stack making the third element on top
apply n-ary operations on the stack
一个典型的操作从栈顶获取一些参数并留下一些结果。
我的堆栈实现为一个数组,其中数据从低内存增长到高内存,指针从高内存增长到低内存。
正如我所见,问题不在于写时复制技术本身,而在于内存管理和垃圾收集。
在 Forth 中,我们不能有运算符重载,并且应该为每个 class 数字有一组明确独立的操作。那么我们有两个选择:
-
- 一组对 bigint 对象(它们的处理程序)的操作,具有手动内存管理,类似于对文件、动态内存缓冲区或其他对象的操作。
-
- 一整套操作,包括独立堆栈,如浮点数操作,具有自动内存管理。
请注意,选项 (2) 在幕后包含 (1)。
引用计数
在选项 (2) 中实现自动内存管理的一种方法是使用专用堆栈(或可能两个堆栈)和引用计数。堆栈包含对对象(缓冲区)的引用。更改数据的操作(如 b::1+
)应该复制缓冲区并在计数器大于 1 时用新的引用替换引用(否则可以在该位置更改数据)。
将项目(引用)放入堆栈应增加其计数器,从堆栈中移除应减少其计数器。当计数器变为 0 时,应释放缓冲区。
b::dup
、b::over
等操作增加计数器。 b::swap
不改变任何计数器。 b::drop
减少计数器(如果计数器为 0 则释放缓冲区)。
将一个项目从堆栈移到 bigint 变量中不应更改结果中的计数器。但是应该减少变量先前值的计数器(如果有的话)。
如果命名变量和常量不够用(例如,拥有用户定义的数组),您可能需要在 API 中引入指针(一种匿名变量)或 bigint 对象的处理程序.
不可变对象
实现选项 (2) 的另一种方法是使用不可变对象和垃圾回收循环。在这种方法中我们不需要计算引用,但需要维护外部指针(包括变量)的列表。
可以在 Peter Sovietov 的 s-expressions 实现中找到此类垃圾收集的一个简单示例:Функциональное программирование на языке Форт ("Functional programming in Forth language" in Russian, but it can be easy translated using Google Translate)。
如何在大数后缀计算中实现堆栈管理的写时复制技术?
我想针对以下操作优化我的系统:
duplicate top of stack
swap the two top elements
copy the second element on stack to the top
rotate the stack making the third element on top
apply n-ary operations on the stack
一个典型的操作从栈顶获取一些参数并留下一些结果。
我的堆栈实现为一个数组,其中数据从低内存增长到高内存,指针从高内存增长到低内存。
正如我所见,问题不在于写时复制技术本身,而在于内存管理和垃圾收集。
在 Forth 中,我们不能有运算符重载,并且应该为每个 class 数字有一组明确独立的操作。那么我们有两个选择:
-
- 一组对 bigint 对象(它们的处理程序)的操作,具有手动内存管理,类似于对文件、动态内存缓冲区或其他对象的操作。
-
- 一整套操作,包括独立堆栈,如浮点数操作,具有自动内存管理。
请注意,选项 (2) 在幕后包含 (1)。
引用计数
在选项 (2) 中实现自动内存管理的一种方法是使用专用堆栈(或可能两个堆栈)和引用计数。堆栈包含对对象(缓冲区)的引用。更改数据的操作(如 b::1+
)应该复制缓冲区并在计数器大于 1 时用新的引用替换引用(否则可以在该位置更改数据)。
将项目(引用)放入堆栈应增加其计数器,从堆栈中移除应减少其计数器。当计数器变为 0 时,应释放缓冲区。
b::dup
、b::over
等操作增加计数器。 b::swap
不改变任何计数器。 b::drop
减少计数器(如果计数器为 0 则释放缓冲区)。
将一个项目从堆栈移到 bigint 变量中不应更改结果中的计数器。但是应该减少变量先前值的计数器(如果有的话)。
如果命名变量和常量不够用(例如,拥有用户定义的数组),您可能需要在 API 中引入指针(一种匿名变量)或 bigint 对象的处理程序.
不可变对象
实现选项 (2) 的另一种方法是使用不可变对象和垃圾回收循环。在这种方法中我们不需要计算引用,但需要维护外部指针(包括变量)的列表。
可以在 Peter Sovietov 的 s-expressions 实现中找到此类垃圾收集的一个简单示例:Функциональное программирование на языке Форт ("Functional programming in Forth language" in Russian, but it can be easy translated using Google Translate)。