Default x86 instruction set
Hi, I noticed that by default x86 32 bit builds are targeted for i386 (at least gcc toolset and its derivatives explicitly specify -march=i386 in the command line). Is there a reason to target for such an ancient instruction set by default? Frankly, I'm not sure that the current Boost code would even run on a real 80386, since there are at least quite a few places with atomic operations, which I think were not present on that CPU. Also, I would like to use cpuid safely in my library, and this operation appeared only in some i486 and all Pentiums, so I would basically target my code for Pentium at the very least. But perhaps we could raise the default to Pentium Pro (i686)? Most Linux distributions already switched to this target for 32 bit builds because of availability of cmov instructions. Windows and OS X, I think, don't support older architectures either.
On 05/05/13 00:02, Andrey Semashev wrote:
Hi,
I noticed that by default x86 32 bit builds are targeted for i386 (at least gcc toolset and its derivatives explicitly specify -march=i386 in the command line). Is there a reason to target for such an ancient instruction set by default?
I take it you mean why is tools/build/v2/tools/gcc.jam adding -march=i386 when using GCC on 32-bit systems. I also think it shouldn't do that. I suppose the reason is due to a limitation of Boost.Build that needs to know what the default is. Most GCC 32-bit binaries will build for i386 by default, even on modern linux distributions.
Frankly, I'm not sure that the current Boost code would even run on a real 80386, since there are at least quite a few places with atomic operations, which I think were not present on that CPU.
Any code that relies on particular instructions should detect what the target is to only use what is supported by the target, with fallback to a portable implementation if possible. It is also possible to not provide portable fallback, in which case the library needs to be ported to each architecture manually.
Also, I would like to use cpuid safely in my library, and this operation appeared only in some i486 and all Pentiums, so I would basically target my code for Pentium at the very least.
There is no problem with making a library that is specific to a given architecture, as long as it is clearly documented and that the limited scope is accepted during review.
But perhaps we could raise the default to Pentium Pro (i686)?
The best solution is to not add any flag, and use whatever the default is.
On 7 May 2013 16:24, Mathias Gaunard wrote:
On 05/05/13 00:02, Andrey Semashev wrote:
Hi,
I noticed that by default x86 32 bit builds are targeted for i386 (at least gcc toolset and its derivatives explicitly specify -march=i386 in the command line). Is there a reason to target for such an ancient instruction set by default?
I take it you mean why is tools/build/v2/tools/gcc.jam adding -march=i386 when using GCC on 32-bit systems.
I also think it shouldn't do that. I suppose the reason is due to a limitation of Boost.Build that needs to know what the default is. Most GCC 32-bit binaries will build for i386 by default, even on modern linux distributions.
Are you sure about that? If the compiler is configured for e.g. i686-pc-linux-gnu then it defaults to -march=i686, and I believe several GNU/Linux distros target i586 or even i686 by default these days.
On 07/05/13 18:17, Jonathan Wakely wrote:
Are you sure about that? If the compiler is configured for e.g. i686-pc-linux-gnu then it defaults to -march=i686, and I believe several GNU/Linux distros target i586 or even i686 by default these days.
AFAIK the latest Debian and its derivatives are still built for i386.
On 7 May 2013 18:16, Mathias Gaunard wrote:
On 07/05/13 18:17, Jonathan Wakely wrote:
Are you sure about that? If the compiler is configured for e.g. i686-pc-linux-gnu then it defaults to -march=i686, and I believe several GNU/Linux distros target i586 or even i686 by default these days.
AFAIK the latest Debian and its derivatives are still built for i386.
That would be pretty silly given that the Linux kernel won't build for i386. I found it hard to believe, so I downloaded the patches from the Debian GCC package: +ifneq (,$(filter $(DEB_TARGET_ARCH), amd64 i386 kfreebsd-i386 kfreebsd-amd64)) + ifneq (,$(filter $(distrelease),etch lenny dapper hardy)) + CONFARGS += --with-arch-32=i486 + else ifneq (,$(filter $(distrelease),squeeze wheezy sid jaunty karmic lucid)) + CONFARGS += --with-arch-32=i586 + else + CONFARGS += --with-arch-32=i686 + endif +endif + +ifneq (,$(filter $(DEB_TARGET_ARCH), hurd-i386)) + CONFARGS += --with-arch=i586 +endif + +ifeq ($(DEB_TARGET_ARCH),lpia) + CONFARGS += --with-arch=pentium-m --with-tune=i586 +endif + +ifneq (,$(filter $(DEB_TARGET_ARCH), amd64 i386 hurd-i386 kfreebsd-i386 kfreebsd-amd64)) + CONFARGS += --with-tune=generic +endif So Debian Etch (initially released 2007) and Lenny (2009) assume i486, Squeeze and Wheezy assume i586. Even if they didn't, the Debian devs would be quite capable of patching the Boost sources if they really wanted to cripple it to support 80386, that doesn't mean it should be the default for upstream Boost.
On Tue, May 7, 2013 at 9:16 PM, Mathias Gaunard < mathias.gaunard@ens-lyon.org> wrote:
On 07/05/13 18:17, Jonathan Wakely wrote:
Are you sure about that?
If the compiler is configured for e.g. i686-pc-linux-gnu then it defaults to -march=i686, and I believe several GNU/Linux distros target i586 or even i686 by default these days.
AFAIK the latest Debian and its derivatives are still built for i386.
No, their "i386" doesn't actually mean 80386: However, Debian GNU/Linux wheezy will *not* run on 386 or earlier processors. Despite the architecture name "i386", support for actual 80386 processors (and their clones) was dropped with the Sarge (r3.1) release of Debianhttp://www.debian.org/releases/stable/i386/ch02s01.html.en#ftn.idp5578656. (No version of Linux has ever supported the 286 or earlier chips in the series.) All i486 and later processors are still supported. http://www.debian.org/releases/stable/i386/ch02s01.html.en
Thank you for the reply. On Tuesday 07 May 2013 17:24:06 Mathias Gaunard wrote:
On 05/05/13 00:02, Andrey Semashev wrote:
Hi,
I noticed that by default x86 32 bit builds are targeted for i386 (at least gcc toolset and its derivatives explicitly specify -march=i386 in the command line). Is there a reason to target for such an ancient instruction set by default?
I take it you mean why is tools/build/v2/tools/gcc.jam adding -march=i386 when using GCC on 32-bit systems.
Yes.
I also think it shouldn't do that. I suppose the reason is due to a limitation of Boost.Build that needs to know what the default is. Most GCC 32-bit binaries will build for i386 by default, even on modern linux distributions.
Not for Ubuntu 13.04, at least. gcc -m32 -dM -E - < /dev/null | grep __i686__ #define __i686__ 1 I also read that Fedora and Mandriva moved to i686 by default (probably, emulating cmov in kernel if running on i586) [1]. And Linux kernel dropped support for 80386 CPUs. [2] I actually read they dropped all CPUs without cpuid (which also includes some 80486) somewhere else, but I can't find it now. FreeBSD removed support for 80386 in 6.0 ([3], [4]). OpenBSD doesn't support both 80386 and some 80486 [5]. Noone uses pure 386 these days, so the default in gcc.jam looks inadequate.
Frankly, I'm not sure that the current Boost code would even run on a real 80386, since there are at least quite a few places with atomic operations, which I think were not present on that CPU.
Any code that relies on particular instructions should detect what the target is to only use what is supported by the target, with fallback to a portable implementation if possible.
It is also possible to not provide portable fallback, in which case the library needs to be ported to each architecture manually.
Technically, yes. But should one waste his time to support this architecture that noone uses anyway? Actually, I was inaccurate in my previous statement; 80386 does support lock prefix, so atomic instructions are safe. That doesn't mean there's no reason to raise the default: my statement regarding cpuid is still in place, and enabling cmov might be benefical for performance.
But perhaps we could raise the default to Pentium Pro (i686)?
The best solution is to not add any flag, and use whatever the default is.
Agreed. But while that is not possible with the current Boost.Build, don't you think we should at least choose a more adequate default? [1] http://boston-linux-unix-general-discussion-list.996279.n3.nabble.com/Linux-... [2] http://www.phoronix.com/scan.php?page=news_item&px=MTI0OTg [3] http://en.wikipedia.org/wiki/History_of_FreeBSD [4] http://www.freebsd.org/releases/6.0R/hardware-i386.html [5] http://www.openbsd.org/faq/faq12.html#FPU
On 7 May 2013 17:17, Andrey Semashev wrote:
Noone uses pure 386 these days, so the default in gcc.jam looks inadequate.
I would have chosen a different word :) It's even been suggested to deprecate 80386 support in GCC, see http://gcc.gnu.org/ml/gcc/2012-12/msg00079.html It hasn't happened yet, but if/when it does the -march=i386 switch will look even more silly.
On Tuesday 07 May 2013 17:34:17 Jonathan Wakely wrote:
On 7 May 2013 17:17, Andrey Semashev wrote:
Noone uses pure 386 these days, so the default in gcc.jam looks inadequate.
I would have chosen a different word :)
It's even been suggested to deprecate 80386 support in GCC, see http://gcc.gnu.org/ml/gcc/2012-12/msg00079.html
It hasn't happened yet, but if/when it does the -march=i386 switch will look even more silly.
Thanks for pointing to that discussion. Turns out 386 actually didn't support atomic ops. :)
On 7 May 2013 17:59, Andrey Semashev wrote:
On Tuesday 07 May 2013 17:34:17 Jonathan Wakely wrote:
On 7 May 2013 17:17, Andrey Semashev wrote:
Noone uses pure 386 these days, so the default in gcc.jam looks inadequate.
I would have chosen a different word :)
It's even been suggested to deprecate 80386 support in GCC, see http://gcc.gnu.org/ml/gcc/2012-12/msg00079.html
It hasn't happened yet, but if/when it does the -march=i386 switch will look even more silly.
Thanks for pointing to that discussion. Turns out 386 actually didn't support atomic ops. :)
Right, that's why GCC's std::string and std::shared_ptr (and tr1::shared_ptr) use a mutex when compiled for i386. You really don't want that if you're running on 486 or better, and *everyone* is running on better.
Jonathan Wakely wrote:
Right, that's why GCC's std::string and std::shared_ptr (and tr1::shared_ptr) use a mutex when compiled for i386. You really don't want that if you're running on 486 or better, and *everyone* is running on better.
boost::shared_ptr silently assumes 486 when compiled for i386.
When testing boost 1.53, we saw an issue with config_test. It failed when using icl 14.0 beta. Q:\boost_1_53_0\libs\config\test>icl -TP /MDd /Zc:forScope /Zc:wchar_t /EHs -Od -DBOOST_ALL_NO_LIB=1 "-I..\..\.." confi g_test.cpp Intel(R) C++ Compiler XE for applications running on IA-32, Version 14.0.0.050 Beta Build 20130417 Copyright (C) 1985-2013 Intel Corporation. All rights reserved. config_test.cpp -out:config_test.exe config_test.obj Q:\boost_1_53_0\libs\config\test>config_test Note: Failed to value-initialize m_ptr_to_member_array[0]. Note: Failed to value-initialize m_ptr_to_member_array[1]. Note: Failed to value-initialize m_ptr_to_member_struct. Note: Failed to value-initialize m_ptr_to_member_struct_array[0]. Note: Failed to value-initialize m_ptr_to_member_struct_array[1]. - Number of subobject initialization failures of a temporary: 5 Note: Failed to value-initialize m_ptr_to_member_array[0]. ..... ..... The reason is the "__INTEL_COMPILER" is 1400 in 14.0 beta. After updating intel.hpp to following at line 183, the "config_test.ex" passed without issue: #if defined(__INTEL_COMPILER) # if (__INTEL_COMPILER <= 1110) || (__INTEL_COMPILER == 1400) || (__INTEL_COMPILER == 9999) # define BOOST_NO_COMPLETE_VALUE_INITIALIZATION # endif #endif Could you fix this issue in the trunk for future releases? Jennifer
Could you fix this issue in the trunk for future releases?
Can you tell me if this is a Win32 specific failure, or does it effect Linux/Darwin as well? I ask because gcc handles this correctly where as msvc does not. Thanks, John.
It is Windows only. Jennifer -----Original Message----- From: John Maddock [mailto:john@johnmaddock.co.uk] Sent: Tuesday, May 07, 2013 10:50 AM To: boost@lists.boost.org; Jiang, Jennifer L Subject: Re: [boost] boost 1.53 config_test failed with icl 14.0 beta
Could you fix this issue in the trunk for future releases?
Can you tell me if this is a Win32 specific failure, or does it effect Linux/Darwin as well? I ask because gcc handles this correctly where as msvc does not. Thanks, John.
Hi John, Instead of adding (__INTEL_COMPILER == 1400), it's better to change (__INTEL_COMPILER <= 1110) to (__INTEL_COMPILER <= 1400) for "Windows only". Because on Windows, icl still does not support all of the value initialization cases. But it is being worked on. Btw, if you'd like to test with the Intel Compiler xe 2013 SP1 beta, you can get the beta by joining the beta program - http://software.intel.com/en-us/forums/topic/392100 Is there any way I can find out when this will be done? Thanks, Jennifer -----Original Message----- From: Jiang, Jennifer L Sent: Tuesday, May 07, 2013 11:10 AM To: John Maddock; boost@lists.boost.org Subject: RE: [boost] boost 1.53 config_test failed with icl 14.0 beta It is Windows only. Jennifer -----Original Message----- From: John Maddock [mailto:john@johnmaddock.co.uk] Sent: Tuesday, May 07, 2013 10:50 AM To: boost@lists.boost.org; Jiang, Jennifer L Subject: Re: [boost] boost 1.53 config_test failed with icl 14.0 beta
Could you fix this issue in the trunk for future releases?
Can you tell me if this is a Win32 specific failure, or does it effect Linux/Darwin as well? I ask because gcc handles this correctly where as msvc does not. Thanks, John.
Andrey Semashev wrote:
Actually, I was inaccurate in my previous statement; 80386 does support lock prefix, so atomic instructions are safe.
Not really. It does support XCHG, LOCK INC, LOCK DEC, but not LOCK CMPXCHG or LOCK XADD. So it's fairly useless for any kind of "serious" atomic work.
On 7 May 2013 17:17, Andrey Semashev wrote:
I also think it shouldn't do that. I suppose the reason is due to a limitation of Boost.Build that needs to know what the default is. Most GCC 32-bit binaries will build for i386 by default, even on modern linux distributions.
Not for Ubuntu 13.04, at least.
gcc -m32 -dM -E - < /dev/null | grep __i686__ #define __i686__ 1
I also read that Fedora and Mandriva moved to i686 by default (probably, emulating cmov in kernel if running on i586) [1].
And Linux kernel dropped support for 80386 CPUs. [2] I actually read they dropped all CPUs without cpuid (which also includes some 80486) somewhere else, but I can't find it now. FreeBSD removed support for 80386 in 6.0 ([3], [4]). OpenBSD doesn't support both 80386 and some 80486 [5].
NetBSD dropped 80386 support too: http://mail-index.netbsd.org/tech-toolchain/2009/02/24/msg000582.html
So it seems, noone's arguing to keep the current default and it is clearly not appropriate. Ok, we just have to choose a better default then. Here's what I suggest: 1. Change the default to i686. 2. Add a notice to the release notes for the release that contains this change. The notice will state what changed and how the default can be changed (by adding instruction-set=xxx to bjam command line). 3. Drop support for 80386, so i486 is the minimum for the whole Boost, unless a specific library has its own requirements. This is already de facto true at least for Boost.Atomic and Boost.SmartPtr, as well as those libraries which uses them or boost::detail::atomic_count. I'm not insisting on #3, although it seems to be a logical conclusion of the discussion. If noone objects I can do the change and provide the text for release notes. PS: Sorry if I'm rushing things. I just want this change to make it into 1.54, and this will make life a little easier for Boost.Log, which I also want to push for this release.
On Wednesday 08 May 2013 10:31:31 you wrote:
So it seems, noone's arguing to keep the current default and it is clearly not appropriate. Ok, we just have to choose a better default then. Here's what I suggest:
1. Change the default to i686. 2. Add a notice to the release notes for the release that contains this change. The notice will state what changed and how the default can be changed (by adding instruction-set=xxx to bjam command line). 3. Drop support for 80386, so i486 is the minimum for the whole Boost, unless a specific library has its own requirements. This is already de facto true at least for Boost.Atomic and Boost.SmartPtr, as well as those libraries which uses them or boost::detail::atomic_count.
I'm not insisting on #3, although it seems to be a logical conclusion of the discussion. If noone objects I can do the change and provide the text for release notes.
PS: Sorry if I'm rushing things. I just want this change to make it into 1.54, and this will make life a little easier for Boost.Log, which I also want to push for this release.
I applied the change to trunk: https://svn.boost.org/trac/boost/changeset/84221
participants (6)
-
Andrey Semashev
-
Jiang, Jennifer L
-
John Maddock
-
Jonathan Wakely
-
Mathias Gaunard
-
Peter Dimov