Intel® C++ Compiler
Support and discussions for creating C++ code that runs on platforms based on Intel® processors.
This community is designed for sharing of public information. Please do not share Intel or third-party confidential information here.
7680 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.

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.
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.
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.