我最近使用SSE替换了一些Vector / Matrix类,现在确保内存正确对齐。
根据this question的答案中的建议,我已经为需要它的类替换了operator new / delete,并开始使用自定义分配器来与STL容器一起使用 - 但是,似乎两者之间存在一些冲突:
要开始使用,我只是简单地复制并粘贴了here中的示例分配器类,当我将它与有问题的类型的std :: vector一起使用时,它编译得很好而没有我的自定义新/删除,但当我更换这些功能时,我收到一个错误"没有匹配功能来调用' operator new'"来自construct()函数,
void construct(pointer p, const T& t) { new(p) T(t); }
我想我已经取代了#34;平常"新的以某种方式掩盖了新的位置?但是,鉴于我无法编写自己的新位置,我不能确定该做什么......我是新的(NPI)整个自定义内存分配事情,所以任何建议都会非常感激!
我使用Clang v3.4(或gcc 4.1.2)在Linux上进行编译;不使用C ++ 11。
非常感谢。
答案 0 :(得分:4)
规范allocator::construct来电::new((void *)p) T(val)
通过省略::
,您可以让名称查找从T
的类范围开始,在此范围内找到您的类范围operator new
并且不再继续({1}} {3}}在找到任何匹配名称的第一个范围停止,即使在某个封闭范围内存在更好的候选者)
(转换为void以防万一用户潜入全局几乎放置的新重载,该重载采用非void指针参数)
PS:正如评论中正确指出的那样,“鉴于我不能自己编写新的位置”是错误的假设。您无法替换全局placement-new,但您当然可以编写一个特定于类的placement new,然后通过类范围查找来获取它。查看name lookup以获取有关分配功能的摘要。
答案 1 :(得分:1)
我建议使用Boost' aligned_allocator:
#include <boost/align/aligned_allocator.hpp>
#include <immintrin.h>
#include <vector>
struct m128i {
// FIXME: ctors/opers with intrinsics would be nice (required?)
__m128i data;
}
int main()
{
std::vector<m128i, boost::alignment::aligned_allocator<m128i, 16> > v;
v.emplace_back();
}
注意:我已更新此内容以使用包装内部成员的结构。有很多库可以做到这一点。这样做的原因很简单:vector_size属性是__m128i与__m256i与__m512i的区别,模板忽略了类型属性,所以我相信它们最终都会使用相同的扩展,这是长期的#34; (或者在非i和d类型的情况下为float / double)。
答案 2 :(得分:0)
我会使用我的起点作为此处给出的分配器:http://en.cppreference.com/w/cpp/concept/Allocator。这实际上是一个最小的分配器。特别是,您根本不需要写construct
。 allocator_traits
,如果找不到您的分配器有construct
方法,则只需为您调用新的位置,使用::
正确确定调用范围(如Cubbi所述),这样您就不会# 39;有这个问题:http://en.cppreference.com/w/cpp/memory/allocator_traits/construct。
我可能根本不会写自定义新/删除。只需编写自定义分配器就足够了,让您的Vector / Matrix类使用自定义分配器通过std::vector
管理数据。