Intel® Integrated Performance Primitives
Deliberate problems developing high-performance vision, signal, security, and storage applications.
6708 Discussions

Select static/dynamic linking within the same code

eos_pengwern
Beginner
625 Views

I'm working on an application to stream compressed video from an embedded PC over a network link to a remote computer, and I'm using the IPP JPEG functions to perform the compression and decompression. Whereas the embedded PC will pretty much always be an Intel Atom running Windows Embedded Standard, the remote PC may be anything at all - perhaps even an Intel-based Mac or Unix box.

Therefore, I've structured my project as a straightforward Windows application for the embedded software, a Qt-based GUI application for the remote computer, and a static image-processing library whose source code is shared by both. Only the static image-processing library calls the IPP JPEG functions.

What I'd like to do is to set things up so that, when I compile the emdedded application, the JPEG calls are bound statically to the Atom-specific version of the IPP, whereas when I compile the remote application they link to the IPP DLLs. If I've read the documentation right (e.g. at ia32\\tools\\staticlib\\readme.htm), one selects static linking by placing "#include ipp_s8.h" in the source code, but I don't want to have to change the source code of each file in my static image-processing library each time I compile it for a different platform - this would be far too error-prone.

Therefore, is there a way of specifying how a static library will link to the IPP, depending upon what sort of application it is itself being linked to?

Any advice would be gratefully received;

Stephen.

0 Kudos
1 Solution
PaulF_IntelCorp
Employee
625 Views

Hello Stephen,

You might be working too hard to minimize the size of your Atom image. By just including a few functions in your application you generally will not add a lot of size to your application and you will not notice any significant performance penalty for the dispatching.

  • Configure your Atom project to link statically and the others to link dynamically. You'll only distribute an EXE for the Atom system and the appropriate shared libraries for the other systems. (Or, compile all of them statically, resulting in one binary per platform.)
  • Then, just use #include "ipp.h". You'll need to spec the lib link list for each project, by specifying the IPP library files to link against.
  • Call ippInit() before calling any other IPP functions.

When you link statically you'll only get the functions you call as part of your executable image. If you link against the standard distribution libraries you will bind with all processor variants for each function that is included with your application, but unless you are severely memory constrained that should not be a problem. Figure that with the JPEG processing you're probably only using a half-dozen IPP functions, so the extra overhead of including all the SIMD variants for a half-dozen functions doesn't amount to much additional space, unless, of course, your memory situation is extremely tight.

See the following KB articles for more general info on linking:

Intel IPP - Intel IPP linkage models - quick reference guide
Simplified Link Instructions for the IPP Library

And check these KB articles for some info on dispatching:

Understanding CPU Dispatching in the Intel IPP Library
IPP Dispatcher Control Functions - ipp*Init*() functions

Note that the last article listed above contains info about the ippInit() function, which is the one you should use to initialize the library, which is necessary for the static link case. This function is compatible with the dynamic link case, so it can also be used in that code.

Paul

View solution in original post

0 Kudos
10 Replies
Vladimir_Dudnik
Employee
625 Views

Hi Stephen,

when you link with ippemerged and ippmerged libraries (and call ippStaticInit function in your application) then on Atom it will dispatch to Atom specific optimized code and on other platforms to appropriate optimized code automatically for you.

Regards,
Vladimir

0 Kudos
eos_pengwern
Beginner
625 Views

Thank you for such a prompt answer, Vladimir.

However, if I understand correctly, this is a way of implementing "custom dynamic linkage". I was hoping to build the embedded application using "single-processor static linkage", to minimize the total binary size and number of files. I guess this would still work; if I did it, could I then put just the Atom-specific DLL onto the Atom PC? Or does doing it this way generate a self-contained DLL to use instead of the precompiled DLLs supplied by Intel? And how do I specify the Atom version of the library when compiling on another platform, if not by selecting a specific header in the source code?

I'm sorry for so many questions: I've read as much about this subject in the documentation as I can find, and looked at the sample code provided in "ipp-samples", but am still somewhat confused.

Stephen.

0 Kudos
PaulF_IntelCorp
Employee
626 Views

Hello Stephen,

You might be working too hard to minimize the size of your Atom image. By just including a few functions in your application you generally will not add a lot of size to your application and you will not notice any significant performance penalty for the dispatching.

  • Configure your Atom project to link statically and the others to link dynamically. You'll only distribute an EXE for the Atom system and the appropriate shared libraries for the other systems. (Or, compile all of them statically, resulting in one binary per platform.)
  • Then, just use #include "ipp.h". You'll need to spec the lib link list for each project, by specifying the IPP library files to link against.
  • Call ippInit() before calling any other IPP functions.

When you link statically you'll only get the functions you call as part of your executable image. If you link against the standard distribution libraries you will bind with all processor variants for each function that is included with your application, but unless you are severely memory constrained that should not be a problem. Figure that with the JPEG processing you're probably only using a half-dozen IPP functions, so the extra overhead of including all the SIMD variants for a half-dozen functions doesn't amount to much additional space, unless, of course, your memory situation is extremely tight.

See the following KB articles for more general info on linking:

Intel IPP - Intel IPP linkage models - quick reference guide
Simplified Link Instructions for the IPP Library

And check these KB articles for some info on dispatching:

Understanding CPU Dispatching in the Intel IPP Library
IPP Dispatcher Control Functions - ipp*Init*() functions

Note that the last article listed above contains info about the ippInit() function, which is the one you should use to initialize the library, which is necessary for the static link case. This function is compatible with the dynamic link case, so it can also be used in that code.

Paul

0 Kudos
eos_pengwern
Beginner
625 Views

Thank you Paul; this makes sense, and your second and fourth links (which I hadn't encountered while trawling the documentation for myself) were particularly helpful.

May I just clarify one further thing? The way I have set things up in Visual Studio, my solution consists of three projects: the statically-linked Atom application, the dynamically-linked GUI application, and a static library containing all the shared code. Each of the the other two applications includes the compiled static library in its list of files for linking.

If I set up the two application projectsto link in these different ways, will they still be able to use the same compiled .lib file generated by the third project? Or should I have two 'library' projects, eachutilizing the same source files but with their own linking (as specified in the "Properties/Librarian" menu) set up as needed?

I suspect this last option may be the best way forward; the library itself only takes a few minutes to compile, and by separating out the Atom and non-Atom versions I could make better use of processor-specific optimisations in the non-IPP parts of the library.

Stephen.

0 Kudos
PaulF_IntelCorp
Employee
625 Views

Hello Stephen,

I think it is a matter of which approach is easiest for you to maintain, especially if you plan to update the projects with new IPP library components, due to an update of the IPP library. Seems like creating two libraries based on the same set of input files, might be the simplest approach. That will accommodate any issues that arise due to the differences in how you build/link against a dynamic versus a static library.

Paul

0 Kudos
eos_pengwern
Beginner
625 Views

Thanks Paul; that makes sense and I think it's what I'll do.

Stephen.

0 Kudos
eos_pengwern
Beginner
625 Views

Hi Paul,

I went ahead and did just that, but it didn't work out quite as I expected. In the static version of my library (linking with the multi-threaded static model), I put the list of files ippacemerged.lib .. libiomp5mt.lib (as given at http://software.intel.com/en-us/articles/simplified-link-instructions-for-the-ipp-library/) into the Project Properties/Librarian/Additional Dependencies menu in VS2008. However, on trying to build the library, after a very long time (during which I thought perhaps the compiler had crashed), it failed with an error message saying "fatal error LNK1189: library limit of 65535 objects exceeded". Yet my source code only makes six or seven IPP calls.

I tried using the 'thread-safe;' single-threaded static libraries, ippacemerged.lib .. ippcore.lib, but compilation failed with a message saying "fatal error LNK1181: cannot open input file 'ippcore.lib'"

If I leave the Project Properties/Librarian/Additional Dependencies menu line blank, and then compile, then I get no compile errors but the resulting application fails to run with a strange error saying "OMP Abort: Initializing libiomp5mt.lib, but found libiomp5mt.lib already initialized". I'm familiar with this error message citing two different versions of the OpenMP threading library, and I know what to do when I see it, but I've never seen it before with both library names the same!

In the dynamic-linked version of my library, using the same source code but linking against the files ippac.lib .. libiomp5md.lib, the compilation completes successfully but there are a large number of warnings of the form "warning LNK4006: __NULL_IMPORT_DESCRIPTOR already defined in ippac.lib(ippac-6.1.dll); second definition ignored".

I'm obviously doing something wrong; how can I troubleshoot all of this?

Thanks,

Stephen.

0 Kudos
PaulF_IntelCorp
Employee
625 Views
Hello Stephen,

Sorry for the delayed reply. I'm not on the forum every day.

There was a mistake in the linker article regarding the single-threaded static library, you should be compiling against "ippcorel.lib" not "ippcore.lib." Note the misspelling.

Not sure why the long link, I just ran a test case on an existing project which only calls about a half dozen functions, using the entire link list, linking against the multi-threaded library and everything worked. The fact that you had a very long link time makes me think something else is wrong...

Any progress with the errors?

Paul
0 Kudos
eos_pengwern
Beginner
625 Views
Thank you Paul.

I think there may be a more fundamental problem with the approach I've been using for the static libraries, namely (1) generating an application which links the IPP libraries statically, (2) generating my own static library that also links the IPP libraries statically, and (3) linking my static library with the application. Presumably this causes the static IPP libraries to be linked in twice, which may well be the cause of conflicts.

Instead, I've switched to just including the source code that was inmy static library directly into the same project as the application. The modest increase in compilation time is offset by the simplicity that I gain through doing it this way. So far it seems to be working, but if I hit further problems I may ask Premier Support for some specific help with the way I have set things up.

Regards,
Stephen.

0 Kudos
PaulF_IntelCorp
Employee
625 Views
Hello Stephen,

Glad to hear you're working again.

BTW, same folks monitoring premeir and the forum; advantage of the forum is some of the engineers also watch the forum threads (when they are able) but not the premier threads, so you can continue to use this site if it is working for you.

Paul
0 Kudos
Reply