sách gpt4 ai đã đi

C++:严格别名与 union 滥用

In lại 作者:可可西里 更新时间:2023-11-01 15:24:27 26 4
mua khóa gpt4 Nike

提前为第一个可能很愚蠢的帖子道歉。虽然有很多关于这个主题的 Material ,但其中很少有是确定的和/或对我来说可以理解的。

Tôi có một cái AlignedArray 模板类,可以在堆上以任意对齐方式动态分配内存(AVX 汇编例程需要 32 字节对齐)。这需要一些丑陋的指针操作。

Agner Fog 在 cppexamples.zip 中提供了一个示例类,它滥用 union 来实现这一点 (../../../optimize/optimization_manuals.zip)。但是,我知道写入 union 的一个成员然后从另一个成员读取会导致 UB。

AFAICT 将任何指针类型别名为 char * 是安全的,但只能在一个方向上。这是我的理解变得模糊的地方。这是我的 AlignedArray 的简化版本类(本质上是对 Agner 的重写,以帮助我理解):

template 
class AlignedArray
{
size_t m_size;
char * m_unaligned;
T * m_aligned;

công cộng:
AlignedArray (size_t const size)
: m_size(0)
, m_unaligned(0)
, m_aligned(0)
{
this->size(size);
}

~AlignedArray ()
{
this->size(0);
}

T const & operator [] (size_t const i) const { return m_aligned[i]; }

T & operator [] (size_t const i) { return m_aligned[i]; }

size_t const size () { return m_size; }

void size (size_t const size)
{
if (size > 0)
{
if (size != m_size)
{
char * unaligned = 0;
unaligned = new char [size * sizeof(T) + alignment - 1];
if (unaligned)
{
// Agner:
/*
union {
char * c;
T * t;
size_t s;
} aligned;
aligned.c = unaligned + alignment - 1;
aligned.s &= ~(alignment - 1);
*/

// Me:
T * aligned = reinterpret_cast((reinterpret_cast(unaligned) + alignment - 1) & ~(alignment - 1));

if (m_unaligned)
{
// Agner:
//memcpy(aligned.c, m_aligned, std::min(size, m_size));

// Me:
memcpy(aligned, m_aligned, std::min(size, m_size));

delete [] m_unaligned;
}
m_size = size;
m_unaligned = unaligned;

// Agner:
//m_aligned = aligned.t;

// Me:
m_aligned = aligned;
}
return;
}
return;
}
if (m_unaligned)
{
delete [] m_unaligned;
m_size = 0;
m_unaligned = 0;
m_aligned = 0;
}
}
};

那么哪种方法是安全的(r)?

1 Câu trả lời

我有实现(替换)mới 的代码和 xóa bỏ运营商,适用于 SIMD(即 SSE/AVX)。它使用以下您可能会觉得有用的函数:

static inline void *G0__SIMD_malloc (size_t size)
{
constexpr size_t align = G0_SIMD_ALIGN;
void *ptr, *uptr;

static_assert(G0_SIMD_ALIGN >= sizeof(void *),
"insufficient alignment for pointer storage");

static_assert((G0_SIMD_ALIGN & (G0_SIMD_ALIGN - 1)) == 0,
"G0_SIMD_ALIGN value must be a power of (2)");

size += align; // raw pointer storage with alignment padding.

if ((uptr = malloc(size)) == nullptr)
return nullptr;

// size_t addr = reinterpret_cast(uptr);
uintptr_t addr = reinterpret_cast(uptr);

ptr = reinterpret_cast
((addr + align) & ~(align - 1));

*(reinterpret_cast(ptr) - 1) = uptr; // (raw ptr)

return ptr;
}


static inline void G0__SIMD_free (void *ptr)
{
if (ptr != nullptr)
free(*(reinterpret_cast(ptr) - 1)); // (raw ptr)
}

这应该很容易适应。显然你会替换 trung tâmmiễn phí ,因为您使用的是全局 mớixóa bỏ用于原始(char)存储。它假设 size_t对于地址运算来说足够宽——在实践中是正确的,但是uintptr_tTừ 会更正确。

关于C++:严格别名与 union 滥用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15274895/

26 4 0
Bài viết được đề xuất: c++ - 通过 union 合法访问 __m128 变量的字节吗?
Bài viết được đề xuất: c++ - 模板类的模板化构造函数的显式实例化
Bài viết được đề xuất: HTTP 状态代码 4xx 与 5xx
Bài viết được đề xuất: c++ - 命名空间和静态类成员链接
可可西里
Hồ sơ cá nhân

Tôi là một lập trình viên xuất sắc, rất giỏi!

Nhận phiếu giảm giá Didi Taxi miễn phí
Mã giảm giá Didi Taxi
Giấy chứng nhận ICP Bắc Kinh số 000000
Hợp tác quảng cáo: 1813099741@qq.com 6ren.com