在堆上分配时对齐内存

时间:2013-08-08 21:50:59

标签: c++ performance optimization alignment

我在C ++中遇到了new()运算符的这个示例实现:

void *operator new(size_t size){
    if(void *mem = malloc(size)){
        cout << "allocated memory" << endl;
        return mem;
    }
    else{
        throw bad_alloc();
    }
}

如何编辑此函数以便可以在特定的“字节边界”上分配内存(我指的是在性能圈中讨论的数据 alignment )?

(我假设这不是由编译器自动完成的 - 或者如果是,那么手动实现它有什么好处吗?)

1 个答案:

答案 0 :(得分:3)

您需要找到一种方法来保留原始指针,否则您的free会非常糟糕。

对齐是一个简单的例子(假设alignment是2 n 值):

 void *aligned = reinterpret_cast<void *>(
        (reinterpret_cast<uintptr_t>(mem) + alignment-1) & ~(alignment-1));

但是,就像我说的那样,你需要将原始指针保存在某个地方。这可能意味着分配“有点extrra”(例如sizeof(void *))。

所以我们最终得到这样的东西:

 assert(!(alignment & alignment-1)); // Don't like aligment not power of 2.

 size_t extra = sizeof(void *);
 void *mem = malloc(size + extra + alignment-1); 
 if (!mem) 
    throw bad_alloc();

 void *aligned = reinterpret_cast<void *>(
        (reinterpret_cast<uintptr_t>(mem) + extra + alignment-1) & ~(alignment-1));
 void **ptr = reinterpret_cast<void **>(aligned); 
 ptr[-1] = mem;
 return aligned; 

然后在操作员删除中,您需要挖出原始指针:

 operator delete(void *mem)
 {
    void **ptr = reinterpret_cast<void **>(mem); // This is the "aligned" pointer. 
    void *orig_mem = ptr[-1]; 
    free(orig_mem);
 }