更小的指针......可能吗?(没有较低的规格系统)

Eng*_*eer 8 c++ memory pointers cuda

在2010年关于光线投射稀疏体素八叉树(SVO)的论文[1]中(道歉;论文需要一段时间才能加载),第3部分指出了一个有趣的内存设置,以节省体素数据上的空间,这几乎总是非常大.

它们指定一个15位相对指针,带有一个1位标志,用于指定是否需要远指针(如果卷数据太大,则标志置位,并且15位指针被视为指向辅助指针,远指针).

为实现这一目标正在做些什么?这与CUDA/GPU有关吗?它是通过C++代码中的某种自定义分配器完成的吗?

如果有的话,如何在C++中完成?

[1] 高效的稀疏体素八分之一:Samuli Laine,Tero Karras; NVIDIA Research

hug*_*omg 12

好吧,你总是可以手动将内存存储在一个数组中,并使用整数索引作为"指针".


Jam*_*mes 8

在C/C++中,您可以以任何您喜欢的方式将数字解释为指针 - 但这意味着您将无法简单地取消引用/添加/减去并执行其他正常的指针操作.相反,您必须使用转换为"true"指针的函数来执行这些操作.

在C++中,你可以很整齐地包裹这一切了一类呈现通过实施指针一样的界面里面operator*,opeartor->和算术运算符.

基于对图2的瞥见,这就是所提出的指针的实现可能看起来像(注意,如果你真的这样做,那么你将要确保该类没有填充到32或64无论如何,它们被分配在2字节边界上 - 通常有编译器特定的指令来控制它.)

class SmallChildPointer{
    public:
        SmallChildPointer(Child* bigChildPointer)
            : value(){
            ptrdiff_t offset = bigChildPointer - base_address;
            if(offset > 0x7fff)
                throw std::runtime_error("too big for a near pointer...");
            value = uint16_t(offset & 0x7fff);
        }

        Child* operator->() const{
            return (Child*)(base_address + value);
        }

        Child const& operator*() const{
            return *(Child const*)(base_address + value);
        }

        Child& operator*(){
            return *(Child*)(base_address + value);
        }

        // do this once, before constructing any of these!
        static void setTheGlobalBaseAddress(void* here){
             base_address = here;
        }

    private:
        uint16_t value;
        static void* base_address;
};
Run Code Online (Sandbox Code Playgroud)


Moo*_*uck 5

您是否注意到每个标准容器都采用一个分配器模板?这样您就可以实现奇怪的内存模型,例如您所描述的那样。(或者通过网络另一台计算机上的数据,或者动态计算的数据......)是的,最好的方法是使用自定义分配器。

template<class T>
class linear_allocator  {
public:
    typedef T* pointer;
    typedef const T* const_pointer;
    typedef T& reference;
    typedef T&& r_reference;
    typedef const T& const_reference;
    typedef T value_type;
    template<class _Other>
    struct rebind {
        typedef linear_allocator<_Other> other;
    };

    linear_allocatorr();
    linear_allocator(const linear_allocator<T>& b);
    linear_allocator(linear_allocator<T>&& b);
    template<class U>
    linear_allocator(const linear_allocator<U>& b);
    ~linear_allocator() throw();
    linear_allocator_base& operator=(const linear_allocator_base& b);
    pointer allocate(size_type count=1, pointer hint=nullptr);
    void deallocate(pointer ptr, size_type count=1) throw();
    static size_type max_size() throw();
    bool operator==(const linear_allocator_base& b) const throw();
    bool operator!=(const linear_allocator_base& b) const throw();
    static void construct(pointer ptr);
    static void construct(pointer ptr, const reference val);
    static void construct(pointer ptr, const r_reference val);
    template<class other>
    static void construct(pointer ptr, const other& val);
    template<class other>
    static void construct(pointer ptr, other&& val);
    //template<class ...Args>
    //static void construct(pointer ptr, Args args);
    static void destroy(pointer ptr);
    static pointer address(reference val) throw();
    static const_pointer address(const_reference val) throw();
    static linear_allocator<T> select_on_container_copy_construction();
    typedef std::false_type propagate_on_container_copy_assignment;
    typedef std::true_type propagate_on_container_move_assignment;
    typedef std::true_type propagate_on_container_swap;
};
Run Code Online (Sandbox Code Playgroud)

我确实没有注意到自定义指针(如自动计算的指针)是最重要的部分。自定义分配器仅允许您将标准容器/算法/等与这些指针一起使用。