[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

Re: i386 compatibility & libstdc++



Arnd Bergmann <arnd@arndb.de> writes:

> No, look at my patch again. If you build without i486 optimization,
> the compiler will see only the extern declaration for 
> __exchange_and_add().

I see. What sonames do you suggest to give to the two copies of
libstdc++? You once said you'd call them libstdc++-i386.so.5,
but that you would also provide them under the name libstdc++.so.5.
This solution seems to have the following properties:

1. It becomes possible to mix native Debian and foreign binaries
   on i486 (provided the dynamic linker can really find the right
   library all the time)
2. Running Debian binaries on foreign systems won't be easy.
   In particular, they all link to libstdc++-i386.so.5, so
   such a library needs to be provided for other systems.
   Mixing that library with that native libstdc++.so.5 might
   cause problems, so anybody running a Debian binary on
   a foreign system would need the binary and all shared libraries
   it links with, even though those libraries have the same 
   sonames as the libraries available on the foreign system.
3. Debian i486 binaries take a significant performance hit.
   The attached program demonstrates that the cost of
   __atomic_add is roughly twice as much if done out-of-line,
   compared to the inline version. On my system, I get
inline: 2.4061
out-of-line: 4.60658

Regards,
Martin

#include <sys/time.h>
#include <stdio.h>

typedef int _Atomic_word;
const int nrepeats = 100000000;

static inline void
atomic_add (volatile _Atomic_word* __mem, int __val)
{
  __asm__ __volatile__ ("lock; addl %0,%1"
			: : "ir" (__val), "m" (*__mem) : "memory");
}

static void
atomic_add2 (volatile _Atomic_word* __mem, int __val);

int main()
{
	struct timeval start, stop;
	double total;
	int i;
	_Atomic_word w = 0;
	// inline
	gettimeofday(&start, 0);
	for (i = 0; i < nrepeats; i++)
		atomic_add(&w, 1);
	gettimeofday(&stop, 0);
	total = stop.tv_sec + 1e-6*stop.tv_usec - 
		(start.tv_sec + 1e-6*start.tv_usec);
	printf("inline: %g\n", total);

	// out-of-line
	gettimeofday(&start, 0);
	for (i = 0; i < nrepeats; i++)
		atomic_add2(&w, 1);
	gettimeofday(&stop, 0);
	total = stop.tv_sec + 1e-6*stop.tv_usec - 
		(start.tv_sec + 1e-6*start.tv_usec);
	printf("out-of-line: %g\n", total);
}

static void
atomic_add2 (volatile _Atomic_word* __mem, int __val)
{
  __asm__ __volatile__ ("lock; addl %0,%1"
			: : "ir" (__val), "m" (*__mem) : "memory");
}



Reply to: