Linux下的内存对齐函数
在Linux下内存对齐的函数包括posix_memalign, aligned_alloc, memalign, valloc, pvalloc,其各个函数的声明如下:
int posix_memalign(void **memptr, size_t alignment, size_t size);
void *memalign(size_t alignment, size_t size);
void *aligned_alloc(size_t alignment, size_t size);
void *valloc(size_t size);
void *pvalloc(size_t size);
1. posix_memalign函数: 分配size大小的字节,并将分配的内存地址存放在memptr中。分配的内存的地址将是alignment的倍数,且必须是2的幂次方和sizeof(void*)的倍数。如果size为0,则函数返回NULL或一个唯一的指针值,以便可以成功传递给free函数。如果分配成功返回0.
2. memalign函数: 是一个废弃的函数,分配size大小的字节,返回已分配的内存地址指针,其内存地址将是alignment的倍数,且必须是2的幂次方。如果分配失败返回NULL。
3. aligned_alloc函数: 用法与memalign函数相同,但是size大小应该alignment的倍数。如果分配失败返回NULL。
4. valloc函数: 是一个废弃的函数,分配size大小的字节,返回已分配的内存地址指针,其内存地址将是页大小(page size)的倍数。如果分配失败返回NULL。
5. pvalloc函数: 是一个废弃的函数,用法与valloc相似.如果分配失败返回NULL。
malloc函数总是返回8字节对齐的内存地址,在64bits上是16字节对齐。
以上所有函数均可以通过free函数进行释放。
alignas也可以用于内存对齐,可以使用alignof来判断是采用多少字节进行对齐,alignas和alignof要配对使用,否则单独调用alignof返回的结果是不准确的。
以下是测试代码(sample_memory_alignment.cpp):
#include <stdlib.h>
#include <malloc.h>
#include <iostream>
int main()
{
for (int i = 0; i < 100; ++i) {
void* p1 = nullptr;
size_t alignment = 64;
size_t size = 512;
int ret = posix_memalign(&p1, alignment, size);
void* p2 = memalign(alignment, size);
void* p3 = aligned_alloc(alignment, size);
void* p4 = valloc(size);
void* p5 = pvalloc(size);
void* p6 = malloc(size);
size_t remainder = 0;
remainder = (unsigned long)p1 % alignment;
if (remainder != 0)
fprintf(stderr, "posix_memalign don't align: %d\n", remainder);
remainder = (unsigned long)p2 % alignment;
if (remainder != 0)
fprintf(stderr, "memalign don't align: %d\n", remainder);
remainder = (unsigned long)p3 % alignment;
if (remainder != 0)
fprintf(stderr, "aligned_alloc don't align: %d\n", remainder);
remainder = (unsigned long)p4 % alignment;
if (remainder != 0)
fprintf(stderr, "valloc don't align: %d\n", remainder);
remainder = (unsigned long)p5 % alignment;
if (remainder != 0)
fprintf(stderr, "pvalloc don't align: %d\n", remainder);
remainder = (unsigned long)p6 % alignment;
if (remainder != 0)
fprintf(stderr, "malloc don't algin: %d\n", remainder);
struct Empty{};
struct alignas(64) Empty64{};
fprintf(stdout, "alignment: %d, %d, %d\n", alignof(Empty), alignof(Empty64), alignof(p6));
free(p1); free(p2); free(p3); free(p4); free(p5); free(p6);
}
fprintf(stdout, "void* size: %d\n", sizeof(void*));
return 0;
}
CMakeLists.txt内容如下:
PROJECT(samples_cplusplus)
CMAKE_MINIMUM_REQUIRED(VERSION 3.0)
# 支持C++11
SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -g -Wall -O2 -std=c11")
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -g -Wall -O2 -std=c++11")
INCLUDE_DIRECTORIES(${PROJECT_SOURCE_DIR})
FILE(GLOB samples ${PROJECT_SOURCE_DIR}/*.cpp)
FOREACH (sample ${samples})
STRING(REGEX MATCH "[^/]+$" sample_file ${sample})
STRING(REPLACE ".cpp" "" sample_basename ${sample_file})
ADD_EXECUTABLE(test_${sample_basename} ${sample})
TARGET_LINK_LIBRARIES(test_${sample_basename} pthread)
ENDFOREACH()
build.sh脚本内容如下:
#! /bin/bash
real_path=$(realpath $0)
dir_name=`dirname "${real_path}"`
echo "real_path: ${real_path}, dir_name: ${dir_name}"
new_dir_name=${dir_name}/build
mkdir -p ${new_dir_name}
cd ${new_dir_name}
cmake ..
make
cd -
编译及测试方法如下:首先执行build.sh,然后再执行./build/test_sample_memory_alignment即可。
更多推荐
所有评论(0)