Intel® oneAPI Threading Building Blocks
Ask questions and share information about adding parallelism to your applications when using this threading library.
Announcements
The Intel sign-in experience has changed to support enhanced security controls. If you sign in, click here for more information.

Making scalable_allocator work

Nav
New Contributor I
469 Views
Tried the following code, and realised that I've got to link to the .so file. But I've noticed that you haven't used any linking in the polygon_overlay example (provided with TBB) under parallel_for. Is there a way to get this program working?
I'm new to linking, and something tells me this is not the way to do it.
Any help would be appreciated.
[bash]#include
#include

using namespace std;
using namespace tbb;

class SomeClass
{
public:
double d;
};

int main()
{
int* i = scalable_allocator().allocate( sizeof(int) );
SomeClass* s = scalable_allocator().allocate( sizeof(SomeClass) );
cout<<"Memory allocated"<
scalable_allocator().deallocate( i, sizeof(int) );
scalable_allocator().deallocate( s, sizeof(SomeClass) );
cout<<"Memory deallocated"<}[/bash]
EDIT: The above program is wrong. It's not the way allocation is done for scalable_allocator. See the following posts for the correction.

0 Kudos
1 Solution
Alexey-Kukanov
Employee
469 Views
Quoting Nav
I understand that I'll have to link to one of these files:
/opt/intel/tbb/tbb30_20100406oss/lib/ia64/cc4.1.0_libc2.4_kernel2.6.16.21/libtbbmalloc.so
/opt/intel/tbb/tbb30_20100406oss/lib/ia64/cc4.1.0_libc2.4_kernel2.6.16.21/libtbbmalloc.so.2
/opt/intel/tbb/tbb30_20100406oss/lib/ia64/cc4.1.0_libc2.4_kernel2.6.16.21/libtbbmalloc_debug.so
/opt/intel/tbb/tbb30_20100406oss/lib/ia64/cc4.1.0_libc2.4_kernel2.6.16.21/libtbbmalloc_debug.so.2
/opt/intel/tbb/tbb30_20100406oss/lib/ia64/cc4.1.0_libc2.4_kernel2.6.16.21/libtbbmalloc_proxy.so
/opt/intel/tbb/tbb30_20100406oss/lib/ia64/cc4.1.0_libc2.4_kernel2.6.16.21/libtbbmalloc_proxy.so.2
/opt/intel/tbb/tbb30_20100406oss/lib/ia64/cc4.1.0_libc2.4_kernel2.6.16.21/libtbbmalloc_proxy_debug.so
/opt/intel/tbb/tbb30_20100406oss/lib/ia64/cc4.1.0_libc2.4_kernel2.6.16.21/libtbbmalloc_proxy_debug.so.2


But it doesn't work:
g++ -ltbb -L/opt/intel/tbb/tbb30_20100406oss/lib/ia64/cc4.1.0_libc2.4_kernel2.6.16.21/libtbbmalloc.so.2 -o scalableAllocator scalableAllocator.cpp


You do not need to link with *proxy* files; otherwise your understanding is correct. The way to do this is either adding -ltbbmalloc (minus, non-capital L, tbbmalloc)to the list of options or adding one of the libraries as an input file (without -L or -l prefix for options). The line you tried did not work because you added -L to the file name.

Read more about -L and -l options of the compiler and linker.

View solution in original post

14 Replies
Ilnar
Beginner
469 Views

Tbb library is linked using -ltbb:
g++ -O3 -DNDEBUG -m64 -o pover ../../common/gui/xvideo.cpp pover_video.cpp polymain.cpp polyover.cpp -ltbb -ltbbmalloc -lpthread -lrt -lpthread -L/usr/X11R6/lib64 -lX11

Nav
New Contributor I
469 Views
Thanks, but using -ltbb won't link the program to the .so file which is necessary for scalable_allocator. I wanted to know how to link to it, so that my program would work.
Ilnar
Beginner
469 Views
you should install .so library into system library path or use one of the LD_LIBRARY_PATH or LD_PRELOAD
or link library statically
Nav
New Contributor I
469 Views
I'm a novice. May I request a bit more detailed directions.

When I type:
echo $LD_LIBRARY_PATH
I get this:
/opt/intel/tbb/tbb30_20100406oss/lib/intel64/cc4.1.0_libc2.4_kernel2.6.16.21:/opt/intel/tbb/tbb30_20100406oss/lib/intel64/cc4.1.0_libc2.4_kernel2.6.16.21

When I try to compile with this:
g++ -ltbb -o scalableAllocator scalableAllocator.cpp

I get this:
/tmp/ccYyHk3R.o: In function `tbb::scalable_allocator::allocate(unsigned long, void const*)':
scalableAllocator.cpp:(.text._ZN3tbb18scalable_allocatorIiE8allocateEmPKv[tbb::scalable_allocator::allocate(unsigned long, void const*)]+0x20): undefined reference to `scalable_malloc'
/tmp/ccYyHk3R.o: In function `tbb::scalable_allocator::allocate(unsigned long, void const*)':
scalableAllocator.cpp:(.text._ZN3tbb18scalable_allocatorI9SomeClassE8allocateEmPKv[tbb::scalable_allocator::allocate(unsigned long, void const*)]+0x20): undefined reference to `scalable_malloc'
/tmp/ccYyHk3R.o: In function `tbb::scalable_allocator::deallocate(int*, unsigned long)':
scalableAllocator.cpp:(.text._ZN3tbb18scalable_allocatorIiE10deallocateEPim[tbb::scalable_allocator::deallocate(int*, unsigned long)]+0x1c): undefined reference to `scalable_free'
/tmp/ccYyHk3R.o: In function `tbb::scalable_allocator::deallocate(SomeClass*, unsigned long)':
scalableAllocator.cpp:(.text._ZN3tbb18scalable_allocatorI9SomeClassE10deallocateEPS1_m[tbb::scalable_allocator::deallocate(SomeClass*, unsigned long)]+0x1c): undefined reference to `scalable_free'
collect2: ld returned 1 exit status


I understand that I'll have to link to one of these files:
/opt/intel/tbb/tbb30_20100406oss/lib/ia64/cc4.1.0_libc2.4_kernel2.6.16.21/libtbbmalloc.so
/opt/intel/tbb/tbb30_20100406oss/lib/ia64/cc4.1.0_libc2.4_kernel2.6.16.21/libtbbmalloc.so.2
/opt/intel/tbb/tbb30_20100406oss/lib/ia64/cc4.1.0_libc2.4_kernel2.6.16.21/libtbbmalloc_debug.so
/opt/intel/tbb/tbb30_20100406oss/lib/ia64/cc4.1.0_libc2.4_kernel2.6.16.21/libtbbmalloc_debug.so.2
/opt/intel/tbb/tbb30_20100406oss/lib/ia64/cc4.1.0_libc2.4_kernel2.6.16.21/libtbbmalloc_proxy.so
/opt/intel/tbb/tbb30_20100406oss/lib/ia64/cc4.1.0_libc2.4_kernel2.6.16.21/libtbbmalloc_proxy.so.2
/opt/intel/tbb/tbb30_20100406oss/lib/ia64/cc4.1.0_libc2.4_kernel2.6.16.21/libtbbmalloc_proxy_debug.so
/opt/intel/tbb/tbb30_20100406oss/lib/ia64/cc4.1.0_libc2.4_kernel2.6.16.21/libtbbmalloc_proxy_debug.so.2


But it doesn't work:
g++ -ltbb -L/opt/intel/tbb/tbb30_20100406oss/lib/ia64/cc4.1.0_libc2.4_kernel2.6.16.21/libtbbmalloc.so.2 -o scalableAllocator scalableAllocator.cpp





Ilnar
Beginner
469 Views
One of the following should work:

g++-L/opt/intel/tbb/tbb30_20100406oss/lib/ia64/cc4.1.0_libc2.4_kernel2.6.16.21/ -ltbb -o scalableAllocator scalableAllocator.cpp

g++-L/opt/intel/tbb/tbb30_20100406oss/lib/ia64/cc4.1.0_libc2.4_kernel2.6.16.21/ -ltbbmalloc -o scalableAllocator scalableAllocator.cpp
Alexey-Kukanov
Employee
470 Views
Quoting Nav
I understand that I'll have to link to one of these files:
/opt/intel/tbb/tbb30_20100406oss/lib/ia64/cc4.1.0_libc2.4_kernel2.6.16.21/libtbbmalloc.so
/opt/intel/tbb/tbb30_20100406oss/lib/ia64/cc4.1.0_libc2.4_kernel2.6.16.21/libtbbmalloc.so.2
/opt/intel/tbb/tbb30_20100406oss/lib/ia64/cc4.1.0_libc2.4_kernel2.6.16.21/libtbbmalloc_debug.so
/opt/intel/tbb/tbb30_20100406oss/lib/ia64/cc4.1.0_libc2.4_kernel2.6.16.21/libtbbmalloc_debug.so.2
/opt/intel/tbb/tbb30_20100406oss/lib/ia64/cc4.1.0_libc2.4_kernel2.6.16.21/libtbbmalloc_proxy.so
/opt/intel/tbb/tbb30_20100406oss/lib/ia64/cc4.1.0_libc2.4_kernel2.6.16.21/libtbbmalloc_proxy.so.2
/opt/intel/tbb/tbb30_20100406oss/lib/ia64/cc4.1.0_libc2.4_kernel2.6.16.21/libtbbmalloc_proxy_debug.so
/opt/intel/tbb/tbb30_20100406oss/lib/ia64/cc4.1.0_libc2.4_kernel2.6.16.21/libtbbmalloc_proxy_debug.so.2


But it doesn't work:
g++ -ltbb -L/opt/intel/tbb/tbb30_20100406oss/lib/ia64/cc4.1.0_libc2.4_kernel2.6.16.21/libtbbmalloc.so.2 -o scalableAllocator scalableAllocator.cpp


You do not need to link with *proxy* files; otherwise your understanding is correct. The way to do this is either adding -ltbbmalloc (minus, non-capital L, tbbmalloc)to the list of options or adding one of the libraries as an input file (without -L or -l prefix for options). The line you tried did not work because you added -L to the file name.

Read more about -L and -l options of the compiler and linker.

Nav
New Contributor I
469 Views
Works! Thanks Alexey! :)

Okay, so tbbmalloc is a library like tbb.
I had used -L after having a look at the man page. I thought it was about specifying the entire directory. Had another look. Concept clearer. Thank you so much.
Nav
New Contributor I
469 Views
Hey, I just realised that the program I wrote above is wrong. The allocate() function takes the number of objects as the parameter. Not sizeof().

The correct code would be (as a person on another website posted) as shown below. I thought scalable_allocator syntax was like malloc. Made me wonder why you decided to allow allocation of n number of objects this way?

Question: In the third line, a temporary object of SomeClass() gets created, right? Could that be avoided?
[bash]
int numberOfObjectsToAllocateFor = 1;
SomeClass* s = scalable_allocator().allocate( numberOfObjectsToAllocateFor );
scalable_allocator().construct( s, SomeClass());
scalable_allocator().destroy(s);
scalable_allocator().deallocate(s, numberOfObjectsToAllocateFor);
[/bash]

Alexey-Kukanov
Employee
469 Views
Reformatting the code from the above post:
[c++]int numberOfObjectsToAllocateFor = 1;
SomeClass* s = scalable_allocator().allocate( numberOfObjectsToAllocateFor );
scalable_allocator().construct( s, SomeClass());
scalable_allocator().destroy(s);
scalable_allocator().deallocate(s, numberOfObjectsToAllocateFor);
[/c++]

class scalable_allocator provides STL-style interface for memory allocation. It's primary purpose is to be used with STL or TBB containers. If you need C-style interface, use scalable_malloc, scalable_free etc. functions.

The necessity to provide a value to the construct() method is also specified by the C++ standard; that's why you need a temporary in the line 3. For default construction, you can use so-called placement operator new:
[c++]new(s) SomeClass();[/c++]
Ilnar
Beginner
469 Views
yes, just use placement new as follow:
[cpp]::new(s) SomeClass();[/cpp]
Ilnar
Beginner
469 Views
Alexey, I think it would preferable to introduce copy_construct in replace to current construct, and construct with default ctor behaviour.
Nav
New Contributor I
469 Views
Thanks Alexey. Some people get to learn C++ fully and then come to TBB. For me it's the other way around :) I had seen the allocator interface earlier, but thought TBB allocators were meant to be used differently.
Now I guess I can just overload 'new' in my class and use scalable_malloc as you suggested.
And vector allocations would go like this:
std::vector> v;

Cool! :)

@ilnarb:
Thanks for helping...you used a scope operator before new. May I know what that was for?
::new
Is it to say that it belongs to a local scope?
Alexey-Kukanov
Employee
469 Views
Quoting ilnarb
Alexey, I think it would preferable to introduce copy_construct in replace to current construct, and construct with default ctor behaviour.

Ilnar, we just implemented the interface prescribed for memory allocators by the current C++ standard. Changing it would make TBB allocator classes incompatible with STL, and thus having no value.
Ilnar
Beginner
469 Views
Alexey, ok!any way,you can overload construct by introducing new one without value. I know, it would tbb specific interface which can lead to problem in case user come back to STL allocator:
[cpp]void construct( pointer p, const value_type& value ) {::new((void*)(p)) value_type(value);}
void construct( pointer p) {::new((void*)(p)) value_type();}[/cpp]
Reply