便携式标记指针 [英] Portable tagged pointers

查看:100
本文介绍了便携式标记指针的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

是否存在一种可移植的方法来在C/C ++中实现带标记的指针,例如某些可以跨平台和编译器工作的文档化宏?或者,当您标记指针时,您将自担风险?如果存在此类辅助功能/宏,它们是任何标准的一部分还是作为开放源代码库提供?

Is there a portable way to implement a tagged pointer in C/C++, like some documented macros that work across platforms and compilers? Or when you tag your pointers you are at your own peril? If such helper functions/macros exist, are they part of any standard or just are available as open source libraries?

对于那些不知道带标记的指针是什么但感兴趣的人来说,这是一种在普通指针中存储一些额外数据的方法,因为在大多数体系结构中,指针中的某些位始终为0或1,因此您可以保留自己的指针.标记/类型/提示中的多余位,只需在要使用指针取消引用某些实际值之前就将其擦除.

Just for those who do not know what tagged pointer is but are interested, it is a way to store some extra data inside a normal pointer, because on most architectures some bits in pointers are always 0 or 1, so you keep your flags/types/hints in those extra bits, and just erase them right before you want to use pointer to dereference some actual value.

const int gc_flag = 1;
const int flag_mask = 7; // aka 0b00000000000111, because on some theoretical CPU under some arbitrary OS compiled with some random compiler and using some particular malloc last three bits are always zero in pointers.

struct value {
   void *data;
};

struct value val;
val.data = &data | gc_flag;
int data = *(int*)(val.data & flag_mask);

https://en.wikipedia.org/wiki/Pointer_tagging

推荐答案

通过确保对象与1 << N的倍数对齐,可以获取地址的最低N位供您个人使用.这可以通过不同的方式独立于平台来实现(对于要基于堆栈的对象,使用alignasaligned_storage,对于动态对象,使用std::aligned_alloc),具体取决于您要实现的目标:

You can get the lowest N bits of an address for your personal use by guaranteeing that the objects are aligned to multiples of 1 << N. This can be achieved platform-independently by different ways (alignas and aligned_storage for stack-based objects or std::aligned_alloc for dynamic objects), depending on what you want to achieve:

struct Data { ... };

alignas(1 << 4) Data d; // 4-bits, 16-byte alignment
assert(reinterpret_cast<std::uintptr_t>(&d) % 16 == 0);

// dynamic (preferably with a unique_ptr or alike)
void* ptr = std::aligned_alloc(1 << 4, sizeof(Data));
auto obj = new (ptr) Data;
...
obj->~Data();
std::free(ptr);

您通过丢弃大量内存来支付,并且随着所需位数的增加而呈指数增长.同样,如果您打算连续分配许多这样的对象,则对于较小的数组,这样的数组将不适合处理器的高速缓存行,这可能会大大降低程序速度.因此,此解决方案是不按比例缩放.

You pay by throwing away a lot of memory, exponentionally growing with the number of bits required. Also, if you plan to allocate many of such objects contiguously, such an array won't fit in the processor's cacheline for comparatively small arrays, possibly slowing down the program considerably. This solution therefore is not to scale.

这篇关于便携式标记指针的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆