• D如何支持写障碍


    原文
    我开始思考编译器中的指针障碍.不把它们看作新类型,而是当作类似切片中的增加了安全性和功能检查区间,但在特例下,如果必要,可在本地和全局绕过它们.
    你仍然拥有今天D所拥有的指针.唯一区别是添加了一种绕过GC写障碍的方法,可能类似:

    core.memory.__raw(T)
    //
    struct __raw(T) {
        T ptr;
        alias ptr this;
        auto opAssign(T rhs) { /*绕过边界检查*/ } 
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    注意别名 本.如果真有这样隐式转换回普通指针的指针.
    另一方面,构造时,总是显式绕过检查.唯一工作是表明你想绕过正常检查,甚至可类似

    slice.ptr[0]
    
    • 1

    本地绕过边界检查.你不必真正用它;严格说是一种可选的性能增强,用于就像可绕过边界检查一样的特例.

    编译器中,同样类似边界检查,可添加:

    -barrier=[none|writes]
    
    • 1

    命令行开关来全局控制它.如果没有编译屏障,不能用一些GC实现.
    屏障自身被转发给druntime函数或llvm内部函数,或适合编译器和垃集的函数(这会使运行时交换出收集器成为额外性能损失,因为屏障也是函数指针,但这是合理决定).
    函数像:

    core.memory.__ptr_write(void** where, void* what)
    
    • 1

    因此,如果实现有最大灵活性.用内部函数和内联,当关闭屏障时,会化简为:

    mov [where], what;
    
    • 1

    注意:

    1,因为从未写入常指针,它不需要写屏障.

    const T* a; a = something;
    
    • 1

    前端不需要特别注意,因为编译不过.
    2,自赋值指针,

    int* a; a++; 
    int[] a;
    a = a[1 .. $];
    
    • 1
    • 2
    • 3

    也不需要写屏障.因为目的是保护改变GC行为的竞争条件,而GC只关心它指向的块,这些操作本身禁止改变它指向的块.如果切片越界,则通不过检查,甚至根据C规则,原始指针超出原始赋值块也是未定义行为.
    只需确保是原子的替换实际指针;确保实际生成inc ptr,而不是读-改-写.我肯定编译器已这样做了,但必须指定来确保.

    编译器前端可闲着,因为后端可检测到这些自修改并消除检查.

    我想,即即使启用它,很多D函数也根本不会生成障碍除非遗漏了些重点.你重新赋值指针到另一块时,就会生成障碍.
    3,也可消除借用引用的障碍,因为你知道GC会看到它在其他地方的规范引用.关键是:写操作会影响GC在运行过程中的行为吗?如果是,则需要保护它.如果不是,可跳过它.安全最好;不需要的额外障碍对性能会造成很小影响,而缺少需要的障碍则是严重运行时错误.
    4,省略了保守的栈扫描,和复制/移动GC实现.但对世代GC和大多数增量和并发GC的实现足够了.当然,需要命令行开关来生成更多代码,来支持其他方案,但是我勾画出可能工作的最简单的.

    5,上面都仅适用直接写至指针,而不是通过指针写.

    char* a;
    a = x; // 有写障
    *a = x; // 没有.
    
    • 1
    • 2
    • 3

    指针值变化才是重要的,GC不关心随机字符值,只关心引用和未引用哪些内存块.

    不同GC实现的好处:
    当前,GC标记阶段停止所有线程,这样就不会竞争,当它标记时,如果GC其他地方工作时,它会变化.有了写障,除非实际写指针,可避免停止线程.
    假设音频线程正在消耗GC资源,但只写入到现有的ushort[]缓冲区,它的活动永远不会使GC工作进程失效,所以可继续运行音频线程.这不需要显式用户工作,也不需要注销它.
    另一个工作线程也许正在处理一些数据,然后发送缓冲一个函数.根据借用指针是否管用,它可能一直运行,但是更简单的,更少漏洞实现会让它完成处理数据,然后只在复制缓冲指针到函数时才因为触发写屏障真正停止.到那时,GC可能几乎完成了,即实际停止时间比当前实现要小得多.

    写障碍是完全的净收入.

  • 相关阅读:
    10月《中国数据库行业分析报告》已发布,深度剖析甲骨文大会Oracle技术新趋势
    C++ Qt开发:标准Dialog对话框组件
    数字通信和fpga概述——杜勇版本学习笔记
    维格云轮播组件入门教程
    开发一个npm包
    jbase实现通用码表
    React报错之Unexpected default export of anonymous function
    类和函数的泛化、偏特化和全特化
    javaWeb项目基于tomcat运行部署后访问方案总结
    云安全解决方案安全保障体系框架
  • 原文地址:https://blog.csdn.net/fqbqrr/article/details/127628981