pragma prefetch:0:macroWithParens

pragma prefetch:0:macroWithParens

jimdempseyatthecove's picture

#define NX (256)
...
#pragma prefetch Array:0:NX

is invalid. The compiler should be able to accept any expression that is deamed constant.

Jim Dempsey

www.quickthreadprogramming.com
15 posts / 0 new
Last post
For more complete information about compiler optimizations, see our Optimization Notice.
Sergey Kostrov's picture

Hi Jim, This is what I've found:
...
The prefetch and noprefetch directives are supported by Itanium® processors only...
...
Also, a correct syntax is as follows:
...
#pragma prefetch
#pragma prefetch a,b
...
So, please take a look at a recent version of Intel® C++ Compiler User and Reference Guides to verify these two notes.

Sergey Kostrov's picture

I've also found an example similar to what you need:
...
#pragma prefetch value:1:80
#pragma prefetch x:1:40
...
It looks like docs have not been verified regarding that pragma and there are some inconsistencies.

jimdempseyatthecove's picture

Sergey, please re-read the first post.

At issue is the preprocessor, with respect to #pragma, is not in line with respect to #if

#define X 40
#define Xtoo (20 * 2)
#if (X == 40)
expands
#endif
#if (Xtoo == 40)
expands
#endif

#pragma prefetch Array:0:X ! ok
#pragma prefetch Array:0:Xtoo ! fails

The only requirement of the 3rd argument to the prefetch is that it be known at compile time (prior to the statement).

The #pragma processing complains about the "(", and the rest of the constant expression.

Jim Dempsey
 

www.quickthreadprogramming.com
Sergey Kostrov's picture

>>...#define Xtoo (20 * 2)...

It is the constant, right? Then, why wouldn't you try to declare it as a constant, like:
...
const int Xtoo = (20 * 2);
...

Sergey Kostrov's picture

Also, you will be very surprised, As soon as '(' or ')' are used in a macro a value of the macro is stored with these characters for that macro and expression is Not evaluated. That is, if I declare:
...
#define 2BY2 ( 2 * 2 )
...
it won't be stored as 4. Period. It will be stored as A=( 2 * 2 ) ( for the preprocessor ).

jimdempseyatthecove's picture

Sergey,

This is valid preprocessor syntax:

#define A 2
#define B 3
...
#if (((A+B)&1)==1)
// odd code expansion
#else
// even code expansion
#endif

At issue here is at times it is a requirement to include the ('s in the macro name.
At other times, due to programmers preference/style, you may wish to include ('s, example

#define myMacro (someoneElsesMacro)

Where the #define includes the ('s due to the situation where someoneElsesMacro, which is outside of your control, may not be suitable for your use (without you adding parenthesis). With or without the added paranthesis, the expression is calcuable by the preprocessor, and should be reduced to the value, whenenever the preprocessor required the evaluation of the literal expression. Such as in the even/odd test above, as well as in the #pragma prefetch pointer:level:offset.

The case where this came up for me, is I have a 3D array, defined at compile time with dimensions NX, NY, NZ. I need to specify the prefetching in terms of these parameters, as well as in terms of a #define REAL ..., where ... is float or double (or in the future longdouble).

It is not unreasonable to want to use a derived parameter in terms of constituent parameters, and then use this where a compile time value is required.

Jim Dempsey

www.quickthreadprogramming.com
Sergey Kostrov's picture

>>#define NX (256)
>>...
>>#pragma prefetch Array:0:NX
>>
>>is invalid.

I think that expansion of the complete statement

#pragma prefetch Array:0:( 256 )

generates the compiler error and this is due to '(' and ')'.

jimdempseyatthecove's picture

Yes, that is what I am saying is the problem. I am laying out the case where it is impractical or impossible to specify the 3rd token without parenthesis. And therefore requesting that the compiler be fixed.

Jim Dempsey

www.quickthreadprogramming.com
Sergey Kostrov's picture

Jim, You can use these two macros for diagnostics:
...
#define _VALUE2( value ) #value
#define _VALUE( value ) _VALUE2( value )
...
#define NX (256)
...
#pragma message ( "# Diagnostics: NX = " _VALUE( NX ) )
...
and in that case it should display:
...
# Diagnostics: NX = (256)
...

jimdempseyatthecove's picture

Sergey, you are still not getting the problem:

Realistic mockup:


	#define CACHE_LINE_SIZE 64

	#define REAL float

	...

	#if (REAL==float)

	#define SIZEOF_REAL 4

	#elif (REAL==double)

	#define SIZEOF_REAL 8

	#else

	#error ??

	#endif

	#define N_REALS_PER_CACHE_LINE (CACHE_LINE_SIZE / SIZEOF_REAL)

	// 4 cache lines ahead

	#define PREFETCH_DISTANCE (N_REALS_PER_CACHE_LINE * 4)

	-----------------

	icc -openmp -O3 -std=c99 -vec-report=3 -mmic diffusion_tiled_HT2.c -o diffusion_tiled_HT2_xphi

	# Diagnostic PREFETCH_DISTANCE =((64 / 4) * 4)

	# Diagnostic N_REALS_PER_CACHE_LINE =(64 / 4)

	# Diagnostic CACHE_LINE_SIZE =64

	# Diagnostic SIZEOF_REAL =4

	# Diagnostic REAL =float

	diffusion_tiled_HT2.c(369): error: expected positive integer

	  #pragma prefetch f1_t_c:0:PREFETCH_DISTANCE

	                            ^

	diffusion_tiled_HT2.c(369): warning #1672: invalid expression in pragma will be ignored

	  #pragma prefetch f1_t_c:0:PREFETCH_DISTANCE

	                             ^

	

Now then, is it reasonable for me to use "()"'s in my #defines?
If so, then why is it unreasonable to have them on the #pragma prefetch
...when the preprocessor and compiler can fully reduce the expression to a constant (as required by prefetch).

Jim Dempsey

www.quickthreadprogramming.com
Sergey Kostrov's picture

>>...Now then, is it reasonable for me to use "()"'s in my #defines?

Don't use '(' and ')' in a define if it is used in #pragma prefetch directive, or use a constant variable of integer type instead.

Sergey Kostrov's picture

>>...Now then, is it reasonable for me to use "()"'s in my #defines?

Don't use '(' and ')' in a define if it is used in #pragma prefetch directive, or use a constant variable of integer type instead.

jimdempseyatthecove's picture

Apparently

const int pfd = PREFETCH_DISTANCE;
#pragma prefetch f1_t_c:0:pfd

works. To quote Martin Johnson (1970's Laugh-In): "but stupid!"

The tokens contain in the macro express a constant. Why clutter-up the code with unnecessary statements.

Jim Dempsey

 

www.quickthreadprogramming.com
Sergey Kostrov's picture

>>Apparently
>>
>>const int pfd = PREFETCH_DISTANCE;
>>#pragma prefetch f1_t_c:0:pfd
>>
>>works. To quote Martin Johnson (1970's Laugh-In): "but stupid!"

Even if I'm not a supporter of different workarounds in codes, like you've done ( ...const int pfd =... ), it is much better to have it instead of waiting for 18 months, or so, for a new release of Intel C++ compiler with a fix.

Login to leave a comment.