Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to specify -march=native using pragmas (or otherwise) in gcc

Tags:

c

gcc

I would like to specify the compiler options for my C code that will be compiled in gcc. I need to do this from within the code because of the way the code will be deployed. This is the code currently which appears to successfully specify the optimization flags.

#pragma GCC optimize ("-O3,-ffast-math")
typedef float v4sf __attribute__ ((vector_size (16)));
typedef union {
  v4sf v;
  float e[4];
} float4;
typedef struct {
  float4 x;
  float4 y;
} complex4;
static complex4 complex4_mul(complex4 a, complex4 b) {
  return (complex4){a.x.v*b.x.v -a.y.v*b.y.v, a.y.v*b.x.v + a.x.v*b.y.v};
}
complex4 f4(complex4 x[], int n) {
  v4sf one = {1,1,1,1};
  complex4 p = {one,one};
  for (int i = 0; i < n; i++) p = complex4_mul(p, x[i]);
  return p;
}

However I would also like to specify -march=native. Is this possible somehow from within the code?

I did try #pragma GCC optimize ("-O3,-ffast-math, -march=native"), but the -march=native part just appears to be ignored. See: https://godbolt.org/g/FjbRcV.

like image 867
graffe Avatar asked Aug 27 '17 18:08

graffe


People also ask

How do you use pragmas?

#pragma Directive in C/C++ The preprocessor directive #pragma is used to provide the additional information to the compiler in C/C++ language. This is used by the compiler to provide some special features. The table of some of #pragma directives in C/C++ language is given as follows, Sr.No.

Does GCC support pragma?

GCC supports several types of pragmas, primarily in order to compile code originally written for other compilers. Note that in general we do not recommend the use of pragmas; See Function Attributes, for further explanation.

How do you use #pragma message?

Use #pragma message to specify a user-defined message within your program code. The first form requires that the text consist of one or more string constants, and the message must be enclosed in parentheses.

What is use of #pragma in C?

A pragma is a compiler directive that allows you to provide additional information to the compiler. This information can change compilation details that are not otherwise under your control. For example, the pack pragma affects the layout of data within a structure. Compiler pragmas are also called directives.


2 Answers

Now I understand. I far as I know there is no other way than using #pragma GCC target

For example:

#pragma GCC target ("arch=skylake-avx512")

But it does not accept native as a parameter. I have added it to your godbolt

https://godbolt.org/g/vm1ZBa

IMO it is wrong approach as they should be passed to the compiler using the command line parameters and properly written makefile

like image 123
0___________ Avatar answered Sep 16 '22 22:09

0___________


So upon consideration it looks like

#pragma GCC target "arch=native"

causes barfing in gcc/config/i386/i386.c, here -

3066 /* Override various settings based on options.  If MAIN_ARGS_P, the
 3067    options are from the command line, otherwise they are from
 3068    attributes.  */
 3069
 3070 static void
 3071 ix86_option_override_internal (bool main_args_p,
 3072                                struct gcc_options *opts,
 3073                                struct gcc_options *opts_set)
 3074 {
  ...
3699   else if (i == pta_size)
 3700     error ("bad value (%s) for %sarch=%s %s",
 3701            opts->x_ix86_arch_string, prefix, suffix, sw);
 3702

I don't see any code in that function that can handle 'native' as an x_ix86_arch_string ..

Instead it looks like 'native' is processed and 'real cpu is detected' earlier on in the command line processing sequence in gcc/config/i386/driver-i386.c:

368 /* This will be called by the spec parser in gcc.c when it sees
369    a %:local_cpu_detect(args) construct.  Currently it will be called
370    with either "arch" or "tune" as argument depending on if -march=native
371    or -mtune=native is to be substituted.
372
373    It returns a string containing new command line parameters to be
374    put at the place of the above two options, depending on what CPU
375    this is executed.  E.g. "-march=k8" on an AMD64 machine
376    for -march=native.
377
378    ARGC and ARGV are set depending on the actual arguments given
379    in the spec.  */
380
381 const char *host_detect_local_cpu (int argc, const char **argv)

So, to summarize, what you are asking for requires a change to gcc .. dynamic cpu determination in gcc seems to be done only once, early on, and even then only if asked for (triggered by command line arguments), this is completed well before any parsing or #pragma processing is started.

Getting dynamic cpu determination aka 'arch=native' functionality in gcc's #pragma sounds more like a feature request for them than a bug fix.

like image 31
Andrew Atrens Avatar answered Sep 19 '22 22:09

Andrew Atrens