# which -march for virtual CPU?

## nsoveiko

i'm installing hardened/linux/amd64/no-multilib/selinux on a vps running under kvm/qemu. the cpu hardware as seen from the guest looks like this:

```
processor       : 0

vendor_id       : GenuineIntel

cpu family      : 6

model           : 2

model name      : QEMU Virtual CPU version 0.12.3

stepping        : 3

microcode       : 0x1

cpu MHz         : 2806.964

cache size      : 4096 KB

fpu             : yes

fpu_exception   : yes

cpuid level     : 4

wp              : yes

flags           : fpu de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pse36 clflush mmx fxsr sse sse2 syscall nx lm rep_good nopl pni cx16 popcnt hypervisor lahf_lm

bogomips        : 5613.92

clflush size    : 64

cache_alignment : 64

address sizes   : 40 bits physical, 48 bits virtual

power management:
```

which -march should i put in CFLAGS? i've tried -march=native only to get emerge failing with "compiler can not create executables" error.

right now there is no -march and as far as i understand from gcc manpage, this is equivalent to building code for the least common denominator, i.e. i386. this kinda sucks  :Sad: 

----------

## krinn

you have pni flags, so i would say march=prescott should be safe, but march=pentium4 if you like a more conservative setting.

----------

## nsoveiko

 *krinn wrote:*   

> you have pni flags, so i would say march=prescott should be safe, but march=pentium4 if you like a more conservative setting.

 

waitaminute... i think both prescott and pentium4 are 32-bit arches. which means that on an x86_64 host without -march compiler would produce generic AMD64/EM64T code, not i386. right?

my main concern mostly is that produced code would be efficient with regards of running in a guest  system with hardened kernel (grsecurity+pax+selinux). aren't there are some hardware features (nx? something else?) of the cpu that compiler should take advantage of?

----------

## krinn

there's also the -march=generic if you wish. and lm is the flag for 64bits capabilities.

And it would produce 32 or 64bits code, that depend on your arch, not the selected cpu.

----------

## nlsa8z6zoz7lyih3ap

 *Quote:*   

> there's also the -march=generic if you wish. and lm is the flag for 64bits capabilities

 

Minor point, but for "generic" you want 

```
 -mtune=generic
```

,

the point being that (to quote from the gcc man page)s:

 *Quote:*   

> -mtune=cpu-type
> 
>            Tune to cpu-type everything applicable about the generated code, except for the ABI and the set of available instructions.
> 
>            The choices for cpu-type are:
> ...

 

I usually start out new installs with -mtune=generic  as it is certain to run. It also  produces pretty good code.  As an example, I find that things will emerge (compile ) faster with this than with -march=ative.     Another safe option is -mtune=native, as (while it is optimized for native) it is supposed to run for any cpu of that architecture.

----------

## nsoveiko

 *krinn wrote:*   

> there's also the -march=generic if you wish. and lm is the flag for 64bits capabilities.
> 
> And it would produce 32 or 64bits code, that depend on your arch, not the selected cpu.

 

actually, there's no -march=generic:

```
$ gcc -march=generic -O2 test.c -o test

test.c:1:0: error: generic CPU can be used only for -mtune= switch
```

 *man gcc wrote:*   

>        -march=cpu-type
> 
>            Generate instructions for the machine type cpu-type.  The choices
> 
>            for cpu-type are the same as for -mtune.  Moreover, specifying
> ...

 

the question remains open: what an honest man shall put in make.conf for this virtual cpu? smoke test of

```
echo 'int main(){return 0;}' > test.c && gcc -O2 -march=nocona test.c -o test && ./test
```

 passes for -march=nocona, core2, corei7, corei7-avx and core-avx-i. which means exactly diddlysquat as all of them support sse3, while this virtual thingy does not.

-march=pentium4 and -march=prescott both result in 

```
test.c:1:0: error: CPU you selected does not support x86-64 instruction set
```

ps. with -march=native gcc thinks it's a pentium-m. bug?

----------

## s4e8

for the best performance, you need to know the host cpu type. then use sth like:

-march=core2 -mnosse4.2 -mnosse4.1 -mnosse4 -mnossse3

Turn off all features VM don't support.

----------

## nsoveiko

 *s4e8 wrote:*   

> for the best performance, you need to know the host cpu type. then use sth like:
> 
> -march=core2 -mnosse4.2 -mnosse4.1 -mnosse4 -mnossse3
> 
> Turn off all features VM don't support.

 

unfortunately this is not an option. vps lives somewhere in the cloud and provider ain't telling.

----------

## nsoveiko

 *nsoveiko wrote:*   

> the question remains open: what an honest man shall put in make.conf for this virtual cpu?

 

further investigation showed that if -march is omitted gcc (x86_64-pc-linux-gnu-4.6.3) implicitly uses undocumented -march=x86-64, which is probably its designation for the least common denominator for the platform. so, i'm leaving -march out of make.conf.

interesting to note that -mtune=native and -mtune=generic produce exactly the same result:

```
16:32 0 spook ~ # CFLAGS="-O2 -pipe -mtune=native" emerge -1 bash && sha1sum /bin/bash

[...]

552c624ba5a50ae7420adf5e7929079312cc2496  /bin/bash

16:35 0 spook ~ # CFLAGS="-O2 -pipe -mtune=generic" emerge -1 bash && sha1sum /bin/bash

[...]

552c624ba5a50ae7420adf5e7929079312cc2496  /bin/bash
```

which is different from -mtune being omitted:

```
16:30 0 spook ~ # cat /var/db/pkg/app-shells/bash-4.2_p45/CFLAGS

-O2 -pipe

16:31 0 spook ~ # sha1sum /bin/bash

ae701fef9986c4cfba8e5ff16bb65f9c32eba3e1  /bin/bash
```

----------

## krinn

-mtune=generic allow generic optimizations, it should be a few only to remain generic, but still few optimize is better than none, and so produce different code.

And if gcc cannot find what cpu you have, going to generic isn't a bad choice in that case.

You better stick with generic than nothing.

----------

