【问题标题】:Smaller pointers... possible? (without a lower spec system)更小的指针......可能吗? (没有较低规格的系统)
【发布时间】:2011-12-30 16:38:29
【问题描述】:

在这篇 2010 年的 paper[1] 中,关于 raycasting sparse voxel octrees (SVOs)(抱歉;该论文需要一段时间才能加载),第 3 部分指出了一个有趣的内存设置以节省空间体素数据,几乎总是非常大。

他们指定一个15位的相对指针,用一个1位的标志来指定是否需要远指针(如果体积数据太大,设置标志,15位的指针被认为指向到辅助的远指针)。

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

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

[1]高效稀疏体素八叉树:Samuli Laine、Tero Karras;英伟达研究

【问题讨论】:

  • PDF 对我不起作用,但我猜它只是数组的索引。编写一个堆分配器来处理数组,然后你就设置好了。

标签: c++ pointers memory cuda


【解决方案1】:

嗯,你总是可以手动将内存存储在一个数组中,并使用整数索引作为“指针”。

【讨论】:

  • 非常多。实际上,这种相对指针一个数组索引。
【解决方案2】:

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

在 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;
};

【讨论】:

    【解决方案3】:

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

    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;
    };
    

    我确实没有注意到自定义指针(就像 Autopulated 一样)是最重要的部分。自定义分配器只是让您使用带有这些指针的标准容器/算法/等。

    【讨论】:

    【解决方案4】:

    另一个选项:我在 Github 上找到了一个带有模板的库,它从静态池中分配,可以低至 1 个字节。

    library's name is "Small pointer" 和贡献者的别名是 HDembinski。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-09-24
      • 1970-01-01
      • 1970-01-01
      • 2015-03-19
      • 2014-08-09
      • 1970-01-01
      相关资源
      最近更新 更多