Intel® oneAPI Threading Building Blocks
Ask questions and share information about adding parallelism to your applications when using this threading library.

Making scalable_allocator work

Nav
New Contributor I
952 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
952 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

0 Kudos
14 Replies
Ilnar
Beginner
952 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

0 Kudos
Nav
New Contributor I
952 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.
0 Kudos
Ilnar
Beginner
952 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
0 Kudos
Nav
New Contributor I
952 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





0 Kudos
Ilnar
Beginner
952 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
0 Kudos
Alexey-Kukanov
Employee
953 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.

0 Kudos
Nav
New Contributor I
952 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.
0 Kudos
Nav
New Contributor I
952 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]

0 Kudos
Alexey-Kukanov
Employee
952 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++]
0 Kudos
Ilnar
Beginner
952 Views
yes, just use placement new as follow:
[cpp]::new(s) SomeClass();[/cpp]
0 Kudos
Ilnar
Beginner
952 Views
Alexey, I think it would preferable to introduce copy_construct in replace to current construct, and construct with default ctor behaviour.
0 Kudos
Nav
New Contributor I
952 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?
0 Kudos
Alexey-Kukanov
Employee
952 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.
0 Kudos
Ilnar
Beginner
952 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]
0 Kudos
Reply