"restrict" or "__restrict" ?

"restrict" or "__restrict" ?

I'm compiling a C++ program with Intel C++ Compiler XE 14.0 using the /Qrestrict compiler flag with Microsoft Visual Studio Ultimate 2013 Update 1. Unfortunetly, the compiler does not recognize the "restrict" keyword - and only recognizes "__restrict". All the examples I find online uses "restrict" which makes we think that I'm doing something wrong . 

/MP /GS /Qrestrict /W3 /Zc:wchar_t /I"..\OptimizedStdLibFunctions" /I"..\InternalExceptions" /I"..\Worker" /I"..\SolutionDefines" /I"..\StringUtilities" /ZI /Od /Fd"Debug\vc120.pdb" /fp:strict /D "_WINSOCKAPI_" /D "NOMINMAX" /D "DEBUG" /D "NOPCH" /D "_UNICODE" /D "UNICODE" /D "_WINDOWS" /D "WIN32" /D "_DEBUG" /D "_LIB" /Zc:forScope /RTC1 /Gd /MTd /Fa"Debug\" /EHsc /nologo /Fo"Debug\" /Fp"Debug\Durability.pch" 

 

18 posts / 0 new
Last post
For more complete information about compiler optimizations, see our Optimization Notice.

"restrict" should work as documented. From my testing, it works well:

C:\Users\sgeng2\Desktop\share>type bug.cpp
void foo(int* restrict  a) { }
C:\Users\sgeng2\Desktop\share>icl bug.cpp /Qrestrict -c
Intel(R) C++ Intel(R) 64 Compiler XE for applications running on Intel(R) 64, Ve
rsion 14.0.3.202 Build 20140422
Copyright (C) 1985-2014 Intel Corporation.  All rights reserved.

bug.cpp

C:\Users\sgeng2\Desktop\share>

Maybe you can test with above simple code to see whether it works? If not, let me know your compiler version.

Thanks,

Shenghong

After further investigation it seems to be a IntelliSense error and not a ICL compiler error:

void *_memcpy(void *restrict b, const void *restrict a, size_t n);

    348    IntelliSense: expected a ')'    c:\Dev\...\optimized_memcpy.h    13    29    OptimizedStdLibFunctions

 

Then, it makes sense! You may report it to IntelliSense team (or maybe because they do not support 'restrict' keyword). :)

Thanks,

Shenghong

__restrict doesn't depend on the compile option /Qrestrict.  Although neither __restrict nor restrict work with MSVC,  __restrict has much wider acceptance among C++ compilers (but rejected as a C++11 item).    Intel seemed to adopt __restrict with some secrecy and it's mis-documented by both Intel and Microsoft.  I suppose the errors in documentation may be an excuse for inconsistent implementation.  As Microsoft has persisted with wrong documentation for years, Intel probably would not act to fix documentation.

I don't know if anyone tested to what extent ICL __restrict matches g++ implementation, for example

https://gcc.gnu.org/onlinedocs/gcc/Restricted-Pointers.html

gcc/g++ don't implement no-aliasing optimizations between pointers with and without __restrict qualifiers, while I think ICL does that.  So it might be possible to write code which breaks under ICL but not other compilers.

The behavior required by /Qansi-alias in ICL up through 14.0 is mandated by both C and C++ standards. So /Qansi-alias would normally be set along with /Qrestrict. ansi-alias seems to be default in ICL 15.0 beta, although the change was intended not to apply to the Windows compiler.  I haven't seen an example where ICL reports violations of it, although I haven't tried hard.  I don't know why there is an option to disable the limited checking which may exist.

Quote:

Inge H. wrote:

After further investigation it seems to be a IntelliSense error and not a ICL compiler error:

void *_memcpy(void *restrict b, const void *restrict a, size_t n);

    348    IntelliSense: expected a ')'    c:\Dev\...\optimized_memcpy.h    13    29    OptimizedStdLibFunctions

 

Probably IntelliSense bug. Maybe this is non relevant to this forum , but I saw a lot of errors caused by IntelliSense after integrating CUDA libraries. Of course everything was compiled.

I'm wondering whether to post a white paper I've been working on where I discuss __restrict extensions.  I suppose the viewpoint expressed by some Intel people in earlier posts on the forum, favoring the /Qrestrict and restrict, may be local to Intel, since I haven't seen that one implemented elsewhere.

I don't have a solution for IntelliSense working only with syntax which is documented by Microsoft (who don't recognize /Qrestrict nor implement __restrict in a useful way). 

I doubt Intel would attempt to influence IntelliSense treatment of CUDA syntax except if it were possible first to assure that OpenMP 4 is handled well, in view of Intel's sometimes stated position supporting the latter as the path toward forward compatibility.  There are enough issues already with reconciling source code between Microsoft's OpenMP 2.0 implementation and more recent OpenMP.  I posted examples of that at

https://github.com/tprince/lcd

where I also use -Drestrict= as the way to accommodate MSVC++ (and -Drestrict=__restrict__ for g++).

I suspect Microsoft put a fair amount of work into implementing auto-vectorization without using __restrict nor typed aliasing rules in VS2012. So they may not be interested in assisting with the latter which permit Intel and gnu compilers to show an advantage, while Microsoft has the advantage when __restrict and the various pragmas aren't used where they might be useful.

I'm not holding my breath for MIcrosoft to do anything about it as they don't support /Qrestrict, nor do they support __restrict in the way that their documentation leads me and others to expect, let alone that this would increase the advantage of Intel C++ over their own.

__restrict works absolutely fine for us with Visual Studio 2012, we've been using it for years. I assume 2013 works just fine as well, but I haven't tested it.  MS claim support for it since VS 2005!

It makes quite a bit of difference to the generated code also, some of our complex conversion functions get a ~10% speed up from using __restrict

To the OP: I would just use __restrict. Its been supported by MS for many years and compiles absolutely fine with gcc 4.8 on our framework as well.

Unlike g++, MSVC++ doesn't accept translation from restrict to __restrict as a pre-processor step.

I see that __restrict doesn't enable any additional auto-vectorization in my tests with VS2012, but it does boost some other cases to 30% of g++ AVX performance, so it seems worth while.

This does reinforce the argument that __restrict is satisfactory across a range of compilers, to the extent that it's surprising ICL doesn't document it better.

I'll update my benchmarks at https://github.com/tprince/lcd and also my own paper with discussion of __restrict compile options.

I recommend to use some macro that takes care of all differences between C++ compilers related to the 'restrict' key word. In another words, do not use it directly in case of cross-platform or cross-compiler development. For example,
...
#ifdef _CPPCOMPILER_A
#define _RESTRICT __restrict
#endif
#ifdef _CPPCOMPILER_B
#define _RESTRICT _restrict
#endif
#ifdef _CPPCOMPILER_C
#define _RESTRICT restrict
#endif
...

The Microsoft compiler (pre-processor) does strange things with macro replacement of restrict variants.  The suggestion is good for most other compilers.

>>The Microsoft compiler (pre-processor) does strange things with macro replacement of restrict variants...

In case of different versions of MSC ( included with VS2005, VS2008, VS2010 ) I did not see any problems. It is not clear for me what '...strange things...' MSC does and clarification is needed.

Maybe your changing of case during macro substitution with MSVC is safer than replacements which have a chance of behaving recursively.  I didn't check details of what had been going wrong after I found out that writing __restrict with no macro substitution was working.  What I tried to do for several years was to use the documented -Qrestrict feature of ICL.  Then, the macro

#define restrict __restrict

was working find with g++ on Windows or linux, but with MSVC it had to be

#define restrict

(remove the restrict qualifiers entirely).

In my experience, MSVC doesn't use __restrict to enable auto-vectorization, but it does make significant improvements in some code which MSVC doesn't vectorize.  So that option has to be engaged properly to make a true determination on whether ICL has an advantage.

I do not consider it as a right form.

>>...#define restrict __restrict

Actually, 'restrict' is a Reserved key word and it is Not recommended to use that form. Since I'm using five major C++ compilers with different implementations of that feature my macro(s) looks like:

.#define _RTRESTRICT __restrict
or
.#define _RTRESTRICT _restrict
etc

( it depends on a C++ compiler, that is, Microsoft, Intel, MinGW, Borland or Turbo )

Sergey,

While I don't believe restrict is a reserved word (except in ICL with -Qrestrict), I agree that your latest suggestion is more portable.

Leave a Comment

Please sign in to add a comment. Not a member? Join today