查找下一个对齐的内存地址
Find next aligned memory address
根据我对维基百科的理解,我可以通过以下按位运算找到下一个最接近元素的索引,并正确对齐。
Assuming the address of the 1st element has the correct alignment.
Assuming the index_alignment is a power of 2.
new_index = (current_index + index_alignment - 1) & ~(index_alignment - 1).
new_address = address_of_1st_element + new_index
index_alignment is 16 bytes/sizeof(type of element) for SSE.
是否可以直接在地址上使用它来从任何给定地址中找到下一个最接近的对齐地址?(这样更快吗?
我正在考虑以下几点以快速完成此操作。
new_address = (current_address + alignment - 1) & ~(alignment -1)
alignment here is 16 for SSE.
当我实现这个时,我发现下面的代码无法编译...
使用Salva和Rotem的建议修复的代码
#include <iostream>
#include <stdint.h>
#define ALIGNMENT 16
using namespace std;
uint32_t* fix_ptr(uint32_t* ptr){
return (uint32_t*)(
(uintptr_t(ptr) + uintptr_t(ALIGNMENT) - 1)
&~ uintptr_t(ALIGNMENT - 1)
);
}
void print_ptr (uint32_t* ptr){
cout << (long long)(void*)ptr << endl;
}
void test(uintptr_t ptr_as_int){
uint32_t* ptr1 = (uint32_t*) ptr_as_int;
cout << "Initial address: ";
print_ptr(ptr1);
uintptr_t alignment = ALIGNMENT;
cout << " alignment: " << alignment << endl;
cout << " alignment - 1: " << (alignment - 1) << endl;
cout << " alignment & alignment: " << (alignment & alignment) << endl;
uint32_t* ptr_fixed = fix_ptr(ptr1);
cout << " fixed address: ";
print_ptr(ptr_fixed);
}
int main(void){
test(1000);
test(16);
}
输出(使用 g++ 代码编译.cpp)
Initial address: 1000
alignment: 16
alignment - 1: 15
alignment & alignment: 16
fixed address: 1008
Initial address: 16
alignment: 16
alignment - 1: 15
alignment & alignment: 16
fixed address: 16
1000 按预期变为 1008,16 变为 16。对于我目前的使用来说可能还可以。不知道有没有更快的方法。
谢谢。
自 C++11 年以来,C++ 标准库中的 memory
标头中具有执行此操作的 std::align
函数。至少在GNU实现(libstdc++)中,std::align
执行与OP几乎相同的位操作:
const auto __aligned = (__intptr - 1u + __align) & -__align;
除了第一个-1
的位置之外,唯一的区别是它使用-__align
而不是~(__align - 1)
,因为两者是等价的。
std::align
还接受一个size
和一个space
参数,并检查在正确对齐后给定的类型是否仍然适合给定的缓冲区/分配space
,以及从space
参数(引用)中减去用于对齐的字节。
以下是没有这些检查的版本,以及仅检查所需的其他参数。
#include <cstddef>
#include <cstdint>
inline void *align(std::size_t alignment, void *ptr) noexcept {
const auto intptr = reinterpret_cast<std::uintptr_t>(ptr);
const auto aligned = (intptr - 1u + alignment) & -alignment;
return reinterpret_cast<void *>(aligned);
}
相关文章:
- C++ 指针的内存地址和指向数组的内存地址如何相同?
- 在C++中打印指向不同基元数据类型的指针的内存地址
- 为什么 vector 的随机访问迭代器给出与指针不同的内存地址?
- 使用内存地址访问结构的属性值
- 为什么C++总是显示十六进制内存地址,而不仅仅是整数?
- 将布局映射到内存地址
- 为什么同一个变量的内存地址不同?
- 无法将内存地址转换为值
- 给定特定内存地址的数组的动态内存分配
- 在 Microsoft Access SQL 中调用自定义 DLL 函数时传递的内存地址无效
- 获取 R 数据帧的内存地址
- c++ 编译器是否保护常量内存地址免受任何更改?
- 如何防止矢量的内存地址更改
- cout 打印内存地址而不是值
- 如何运行外部程序,向其传递内存地址以读取/写入?
- 循环中的变量被设置为下一个数组的元素始终具有相同的内存地址?
- 重载 ostream << 运算符,指针作为参数,导致输出上的内存地址
- C++在变量的内存地址上做什么来"deallocate"它?
- 在指向现有内存地址的 hpp 文件中声明成员函数的最佳方法
- 为什么我无法获取 MSVS2019 / C++ 中字符或uint8_t变量的内存地址?