在处理小对象时,可以使用哪些分配器与STL一起使用.我已经尝试过使用Boost的池分配器,但没有性能提升(实际上,在某些情况下会有相当大的降级).
下面测试用例运行的内存上在回路下列当使用OpenMP的"后MT节"消息32台机器(投掷的std :: bad_alloc的),但是,如果表示OpenMP的编译指示被注释的那样,代码运行通过完成精细,所以会出现,当内存并行线程分配,它不是免费的正确,因此,我们耗尽内存.
问题是下面的内存分配和删除代码是否有问题,或者这是gcc v4.2.2或OpenMP中的错误?我也试过gcc v4.3并且失败了.
int main(int argc, char** argv)
{
std::cout << "start " << std::endl;
{
std::vector<std::vector<int*> > nts(100);
#pragma omp parallel
{
#pragma omp for
for(int begin = 0; begin < int(nts.size()); ++begin) {
for(int i = 0; i < 1000000; ++i) {
nts[begin].push_back(new int(5));
}
}
}
std::cout << " pre delete " << std::endl;
for(int begin = 0; begin < int(nts.size()); ++begin) {
for(int j = 0; j < nts[begin].size(); ++j) {
delete nts[begin][j]; …Run Code Online (Sandbox Code Playgroud) 使用STL容器时,我不确定默认分配器分配的int是否已归零.以下代码表示问题的"是":
#include <map>
#include <iostream>
int main() {
using namespace std;
map<int, int> m;
cout << m[1234] << endl;
}
Run Code Online (Sandbox Code Playgroud)
由于没有文件证实这一点,我不敢把它视为理所当然.
通过new/ malloc和内存分配有什么区别allocator?
为什么我们永远需要载体的独立内存分配器,如果我们的选择new和malloc?
我想提高列表和映射的特定用法的性能,其中项目的数量具有100000的硬限制.在这种情况下,STL默认分配器显然不是最佳选择,因为清理所有成千上万的小物件需要很长时间(> 10秒!).更不用说所有其他潜在问题了.
因此,显然要改进这一点,我可以预先分配正确的内存量以包含所有列表/映射节点.到目前为止,我已经能够实现默认分配器的工作版本(通过从std :: allocator_traits派生),它为每个节点使用alloc/free.但我正在努力找出如何修改它以允许"有状态"使用,例如,我非常简单的堆栈:
using namespace std;
class MemPoolStack
{
public:
size_t Size;
size_t Mult;
size_t Total;
size_t Top;
size_t Last;
unique_ptr<byte[]> Data;
unique_ptr<size_t[]> Nexts;
MemPoolStack(size_t size, size_t mult) :
Size(size),
Mult(mult),
Total(size * mult),
Top(0),
Last(0),
Data(new byte[Total]),
Nexts(new size_t[Size])
{
}
size_t& Next(size_t i)
{
return *(Nexts.get() + i);
}
void* Pop()
{
byte* p = nullptr;
if(Top<Size)
{
p = Data.get() + (Top * Mult);
bool last = (Top==Last);
size_t next = last ? Top+1 : …Run Code Online (Sandbox Code Playgroud) 上下文:我正在编写一个库,该库为想要自定义内存分配以实现实时性能的用户提供了许多stdlib数据结构中的自定义分配器。
我想与std::promise和使用自定义分配器std::future。我的理解是,当分配器传递给时std::promise,其future对象也使用该自定义分配器。
我的测试将覆盖new和delete全局变量,以跟踪调用默认操作符的次数。我还实现了一个自定义分配器,该分配器使用malloc,free但使用不同的状态来计数分配/取消分配(在实际示例中,它将被实时安全分配器代替)。
看来,当我要求std::promise::set_value使用“大”对象时,将调用全局运算符new和delete,即使promise使用了自定义分配器构造了全局操作符也是如此。
这是一个基本的例子。(为简便起见,删除了分配器样板,您可以在Gist上看到完整的可编译版本:https://gist.github.com/jacquelinekay/a4a1a282108a55d545a9)
struct Foo {
std::vector<int, InstrumentedAllocator<int>> bar;
};
int main(int argc, char ** argv) {
(void) argc;
(void) argv;
InstrumentedAllocator<void> alloc;
std::promise<Foo> promise_(std::allocator_arg, alloc);
std::shared_future<Foo> future_ = promise_.get_future().share();
// Start a thread that blocks for a few ms and sets the future value
std::thread result_thread(
[&promise_]() {
Foo result;
result.bar.push_back(1);
result.bar.push_back(2);
result.bar.push_back(3);
// test_init starts counting …Run Code Online (Sandbox Code Playgroud) 这次我和分配器一起尝试,并且觉得有很多机会泄漏资源.所以我想如果我std::unique_ptr以前处理它们会怎样.我试着用std::vector分配器试了一下手.我的代码是这样的: -
// allocator
#include <iostream>
#include <vector>
#include <memory>
using namespace std;
class X
{
int x,ID;
static int i;
public:
X()
{
cout<<"constructing ";
ID=++i;
cout<<"ID="<<ID<<'\n';
}
X(int a)
{
x=a;
cout<<"constructing ";
ID=++i;
cout<<"ID="<<ID<<'\n';
}
void get()
{
cout<<"enter x: ";
cin>>x;
}
void disp()
{
cout<<"x="<<x<<'\t';
}
~X()
{
cout<<"destroying ID="<<ID<<'\n';
}
};
int X:: i=0;
int main()
{
ios::sync_with_stdio(false);
vector<X> v;
auto alloc = v.get_allocator();
unsigned int i=0;
X *p(alloc.allocate(5));
for …Run Code Online (Sandbox Code Playgroud) 我在这里找到一些词语http://en.cppreference.com/w/cpp/memory/scoped_allocator_adaptor/construct
if
std::uses_allocator<T, inner_allocator_type>::value==true(类型T使用分配器,例如它是一个容器)如果
std::is_constructible<T, std::allocator_arg_t, inner_allocator_type, Args...>::value==true,然后打电话
Run Code Online (Sandbox Code Playgroud)std::allocator_traits<OUTERMOST>::construct( OUTERMOST(*this), p, std::allocator_arg, inner_allocator(), std::forward<Args>(args)... );
所以,我做了一个简单的测试
struct use_arg {
template <typename Alloc>
use_arg(std::allocator_arg_t, Alloc &, int i)
{ std::cout << i << " in use_arg()\n"; }
};
namespace std {
template <typename A> struct uses_allocator<use_arg, A>: true_type {};
} // namespace std
void test_scoped()
{
std::scoped_allocator_adaptor<std::allocator<use_arg>> sa;
auto p = sa.allocate(1);
sa.construct(p, 4);
sa.destroy(p);
sa.deallocate(p, 1);
}
Run Code Online (Sandbox Code Playgroud)
但是gcc和clang给了我这些错误https://gist.github.com/anonymous/3e72754a7615162280fb
我也写use_a了替换use_arg.它可以成功运行.
struct …Run Code Online (Sandbox Code Playgroud) 这个主题出现在这个主题中,关于对Visual Studio 2015的std :: list :: sort()的更改:
`std :: list <> :: sort()` - 为什么突然切换到自上而下策略?
新版本的std :: list :: sort不需要默认的可构造std :: list,因为它只使用迭代器,并且不创建任何本地列表,因此列表不能是默认值无关紧要建造.先前版本使用本地列表(注意 - 列表的每个实例都涉及动态分配标记节点):
typedef list<_Ty, _Alloc> _Myt;
// ...
const size_t _MAXBINS = 25;
_Myt _Templist, _Binlist[_MAXBINS];
Run Code Online (Sandbox Code Playgroud)
我正在尝试创建一个非默认的可构造列表,使用Visual Studio 2015版本来测试对std :: list :: sort()的更改如何处理.
首先,我尝试了Microsoft C++ 11最小分配器示例.udpate - 为了Jonathan Wakely的回答,我不得不换一行来证明这个问题:
template <class T>
struct Mallocator
{
typedef T value_type;
// Mallocator() noexcept {} // replaced this line from the Microsoft example
Mallocator(T) noexcept {} // no default constructor …Run Code Online (Sandbox Code Playgroud) 以下代码可以正常编译:
#include <iostream>
#include <memory>
int main()
{
const int * a = new int(5);
std::cout << *a << std::endl; // Prints 5
// *a = 5; // Compiler error.
using at = std::allocator_traits<typename std::allocator<int>>;
auto alloc = std::allocator<int>();
at::construct(alloc, a);
std::cout << *a << std::endl; // Prints 0
}
Run Code Online (Sandbox Code Playgroud)
隐藏在libstdc ++中
::new((void*)a) int;
Run Code Online (Sandbox Code Playgroud)
但是a是const!
这是未定义的行为吗?还是新放置的位置不算作修改?我修改了的值*aconst。据我了解,这是不允许的:
通过非常量访问路径修改const对象,并通过非易失性glvalue引用volatile对象会导致未定义的行为。