Possible Bugs in TBB Memory Allocators

Possible Bugs in TBB Memory Allocators

Shankar的头像

I was working with TBB memory allocators and I came across two problemswhich might possibly be bugs.


Problem 1:


The TBB allocators, scalable_allocator and cache_aligned_allocator have defined the allocate methodlike pointer allocate(size_type n, void* hint =0) , while the std::allocator defines the allocatormethod like pointer allocate(size_type _Count, const void _FARQ* hint = 0) because of which i get a compiler error whenIreplacestd::allocator with TBB allocators.I found this problem when I replacedthe default allocator of boost::multi_arraywith TBB allocators.


The TBB memory allocators (both cache_aligned_allocator and scalable _allocator) should also define the second argument of allocate method as const void* as the std::allocator does.This would solve the problem that I found with using TBB allocators with boost::multi_array.


Problem 2:


I found that thecache aligned allocator crashes for the following sample in a 32 bit Windows operating system on a Intel core-2, 1.86GHzmachinebuilt with VisualStudio 2005.The same sample doesnot crash with scalable allocator though.


I made sure that the memory allocator library is available for cache_aligned_allocator to use scalable_malloc instead of malloc but still it crashes.I see the virtual memory of the process increasing and then crashes after a limit.What suprises me is that the problem doesnot happen when i replace the cache_aligned_allocator with scalable_allocator..


I would want to know whether it is really a bug or Im doing something wrong here??


#include
#include
#include "tbb/tick_count.h"
#include "tbb/cache_aligned_allocator.h"


#define KILO 1024
#define MEGA (KILO * KILO)


void allocatorTest(tbb::cache_aligned_allocator& allocator, unsigned int iterations, unsigned int size)
{
std::valarray allocations(iterations);
{
float duration = 0.0;
float time;
unsigned int n = 1;
while (duration < 200.0) {
tbb::tick_count begin = tbb::tick_count::now();
for (unsigned int j = 0; j < n; ++j) {
for (unsigned int i = 0; i < iterations; ++i) {
allocations[i] = allocator.allocate(size);
}
&nbsp
; for (unsigned int i = 0; i < iterations; ++i) {
allocator.deallocate( allocations[i], size);
}
}
tbb::tick_count end = tbb::tick_count::now();
duration = ((end - begin).seconds() *1000);
n += n;
}
n /= 2;
time = ((duration / (n * iterations)) * 1000.0);
std::cout << "cache_aligned_allocator" << " : " << std::setw(5) <<
iterations << ' ' << size << " byte allocs + frees in " << time <<
" micro-seconds per alloc-free pair." << std::endl;
}
}


int main()
{
tbb::cache_aligned_allocator allocator;


allocatorTest(allocator, 1, (64 * KILO));
allocatorTest(allocator, 10, (64 * KILO));
allocatorTest(allocator, 100, (64 * KILO));
allocatorTest(allocator, 1000, (64 * KILO));
allocatorTest(allocator, 10000, (64 * KILO));
allocatorTest(allocator, 1, (1 * MEGA));
allocatorTest(allocator, 10, (1 * MEGA));
allocatorTest(allocator, 100, (1 * MEGA));
allocatorTest(allocator, 1000, (1 * MEGA));
allocatorTest(allocator, 1, (128 * MEGA));
allocatorTest(allocator, 10, (128 * MEGA));
allocatorTest(allocator, 10, (1024 * MEGA));


return 0;
}

2 帖子 / 0 new
最新文章
如需更全面地了解编译器优化,请参阅优化注意事项
Alexey Murashov (Intel)的头像

Thank you,


I modified all "allocate" functions in TBB, added "const" prefix to "hint" argument. I couldn't change the type of "hint" to const void _FARQ* because it is available only on Windows and the code is not portable in this case.


I suppose the change will appear in the next developer release.


The reason of problem #2 is trying to allocate too much memory. Cache_aligned_allocator throws std::bad_alloc exception in this case. Standard malloc reports error too. Consider changing allocate to malloc in your example:


for (unsigned int j = 0; j < n; ++j) {


for (unsigned int i = 0; i < iterations; ++i) {


errno = 0;


//allocations[i] = allocator.allocate(size);


allocations[i] = (char*)malloc(size);


if (errno) {perror("");}


}


for (unsigned int i = 0; i < iterations; ++i) {


//allocator.deallocate( allocations[i], size);


free (allocations[i]);


}


}


You will get "Not enough space" error messages printed by perror().


Another problem here is the difference in scalable_allocator and cache_aligned_allocator behavior. Cache_aligned_allocator throws an exception, but scalable_allocator doesn't. According to C++ standard, "allocate" method may throw exception if not enough memory is available. We will consider adding exception throwing to scalable_allocator.


Best regards,


Alexey

登陆并发表评论。