Intel® C++ Compiler
Community support and assistance for creating C++ code that runs on platforms based on Intel® processors.
7873 Discussions

Use of 'restrict' in library called from Microsoft C++

I have an Intel C++ library for doing optimised math functions, each of which is called from a main application compiled with MSVC. In some cases, the compiler advises that to promote vectorization, I ought to apply the 'restrict' keyword to my array arguments. For example, in the case of a very simple routine for vectorized division:

[cpp]void div(const int &n, double * restrict x, const double * restrict y)
    int copy_n = n;              // Optimisation suggested by Intel C++ compiler
    for (int i=0; i /= y;

The problem is that 'restrict' is not standard C++ and is supported in different ways by different compilers; in particular, later versions of the Microsoft C++ compiler implement it via the __restrict keyword, while earlier versions don't support it at all. I therefore have this rather grotesque construct in the header file:

[cpp]#ifdef __INTEL_COMPILER
# define RESTRICT restrict
#elif defined _MSC_VER
# if _MSC_VER >= 1400
#  define RESTRICT __restrict
# else
#  define RESTRICT
# endif
# define RESTRICT

void div(const int &n, double * RESTRICT x, const double * RESTRICT y);

This compiles quite happily with either the Microsoft or Intel compilers, but I find that I cannot link; the linker tells me:

[bash] error LNK2019: unresolved external symbol "__declspec(dllimport) void __cdecl div(int const &,double *,double const *)"[/bash]

This problem goes away if I delete all references to 'restrict', so that's obviously what's causing the problem.

There's presumably a right way to do this; can anyone tell me what it is?



0 Kudos
4 Replies
If you know that it is safe to vectorize the code the you may use

#pragma ivdep

just above the for loop. This should vectorize the loop and you can remove the restrict from the fuction signature.

0 Kudos
Black Belt
This looks as if you have provoked a mangling mis-match, e.g. by not using the prototypes consistently.
In my experience, the acceptance of __restrict by Microsoft compilers is very limited. If you're implying that restrict is unreliable across calls between Microsoft- and Intel- compiled C++, you may have a point; if so, it should not be difficult for you to pose an example which demonstrates it and would help determine whether the problem is on the Intel side.
Some Intel compilers have accepted __restrict as equivalent to __restrict__ but I've seen no documentation on this point.
According to my understanding, use of one of the restrict extensions should be safer than #pragma ivdep, as it retains more compiler checking. Now that ICL supports also #pragma simd, we must consider the extent to which it may be riskier yet.
0 Kudos
I don't particularly claim it is a problem on the Intel side, except that I wouldn't be doing this as a library if I didn'twant to use a different compiler for the math-intensive parts of the application(what I'd really like to be doing is building the whole application using Intel C++, but the application uses the Qt libraries which do not support the current version of Intel C++ - another story..)

Anyway, as it happens,if I compile the library itself in MSVC and use '__restrict' explicitly, it still won't build. Perhaps there is a more fundamental problem with applying the restrict keyword to arguments of an exported function, in which case abandoning this approach and using a pragma, as Om suggested, may be a sounder approach.
0 Kudos
Black Belt
As I've had no success myself with the Microsoft __restrict, I'm not totally surprised. MSVC doesn't perform many optimizations which would be enabled by it, so perhaps they didn't think it important to support.
0 Kudos