[mythtv] Compiliation error with Intel's compiler (icc) and mythtv

Mark Rickard mrickard at DEPAUW.EDU
Thu Feb 20 22:08:59 EST 2003


Compiliation error with Intel's compiler (icc) and mythtv

I have been trying to compile mythtv with Intel's C/C++ compiler (icc),
but so far, I have NOT been successful.  The reason for doing this is
increased performance.  Benchmarks of gcc 3.2 versus icc 7.0 show that
icc typically creates faster code when dealing with floating-point
intensive calculations (see
http://www.coyotegulch.com/reviews/intel_comp/intel_gcc_bench2.html).  I
have seen similar results when dealing with molecular dynamics
simulations that use only double precision variables.  Also, icc
supports auto-vectorization (MMX, SSE, and SSE2) that can dramatically
improve floating-point performance on Pentium 4 chips. 
Auto-vectorization is a process in which the compiler rewrites certain
types of loops to utilize SIMD instructions.  Finally, there is free
version of icc available at
http://www.intel.com/software/products/compilers/clin/noncom.htm for
non-commercial use.

The process for building mythtv with icc is somewhat long, but the steps
are listed below.  A description of the step is given in the text, and
the actual commands are listed below the description.  I am running
Gentoo 1.4 on an Athlon-XP 1800+ (1.54 GHz) with icc 7.0 in addition to
gcc 3.2.1.  Some of the steps below may vary for different
distributions.

1. Find where your system stores the QT specs.  On Gentoo, it is in
"/usr/qt/3/mkspecs".  There should be a directory called "linux-g++"
already there.  Make a new directory called "linux-icc" in
"/usr/qt/3/mkspecs", and copy the file "qplatformdefs.h" from
"linux-g++" to "linux-icc".  Copy the attachment "qmake.conf" from this
email into "linux-icc".

cd /usr/qt/3/mkspecs
mkdir linux-icc
cp linux-g++/qplatformdefs.h linux-icc
cp ~/qmake.conf linux-icc

2. Get a recent CVS copy of mythtv, and copy the directory "MC" to
"MC-icc".  There are a few significant changes that need to be made, and
it is a good idea to preserve the original code.

cd ~
cp -R MC MC-icc

3. cd into "MC-icc" and apply the patches "settings.patch", "mmx.patch",
and "XJ.patch" that are attached to this email using the command "patch
-p1 < patch_file".  The patch "mmx.patch" needs to be applied because
icc chokes on the assembly in the function mm_support() contained in
"MC-icc/libs/libmythtv/mmx.h".  I set the function to always return 1 to
indicate that mmx instructions are supported by the current CPU. 
"XJ.patch" adds a missing pthread.h include file to
"MC-icc/libs/libmythtv/XJ.cpp".

cd MC-icc
patch -p1 < ~/settings.patch
patch -p1 < ~/mmx.patch
patch -p1 < ~/XJ.patch

4. Clean up the CVS tree using "make distclean".  Configure libavcodec
and mythtv.  Note:  The C/C++ flags in "qmake.conf" and the shell
variables are specifically optimized for the Pentium 3 and Athlon-XP. 
Older chips will need a different set of optimizations (see icc -help). 
For the Pentium 4, replace "-tpp6 -xK" with "-tpp7 -xW" in "qmake.conf"
(change it in the variables QMAKE_CFLAGS, QMAKE_LINK, and
QMAKE_LINK_SHLIB) and the shell variables.

make distclean
export CFLAGS="-g -O3 -Ob2 -tpp6 -xK -unroll -i_dynamic"
export CXXFLAGS="-g -O3 -Ob2 -tpp6 -xK -unroll -i_dynamic"
./configure --enable-a52bin --enable-shared --cc=icc
qmake -spec /usr/qt/3/mkspecs/linux-icc -o Makefile mythtv.pro

5. Build mythtv with "make".

make

The build process will error out on the file
MC-icc/libs/libmythtv/RTjpegN.cpp with the following errors:

icc -c -g -O3 -Ob2 -tpp6 -xK -ip -unroll -fno-rtti -i_dynamic -w
`freetype-config --cflags` -D_REENTRANT  -D_GNU_SOURCE
-DPREFIX=\"/usr/local\" -DEXTRA_LOCKING -DMMX -DQT_NO_DEBUG
-DQT_THREAD_SUPPORT -I/usr/local/include -I../libmyth -I..
-I/usr/qt/3/include -I/usr/qt/3/mkspecs/linux-icc -o RTjpegN.o
RTjpegN.cpp

RTjpegN.cpp(1543): error: no suitable constructor exists to convert from
"long long" to "mmx_t"
  static mmx_t fix_141          = (long long)0x5a825a825a825a82LL;
                                  ^
RTjpegN.cpp(1544): error: no suitable constructor exists to convert from
"long long" to "mmx_t"
  static mmx_t fix_184n261      = (long long)0xcf04cf04cf04cf04LL;
                                  ^
RTjpegN.cpp(1545): error: no suitable constructor exists to convert from
"long long" to "mmx_t"
  static mmx_t fix_184          = (long long)0x7641764176417641LL;
                                  ^
RTjpegN.cpp(1546): error: no suitable constructor exists to convert from
"long long" to "mmx_t"
  static mmx_t fix_n184         = (long long)0x896f896f896f896fLL;
                                  ^
RTjpegN.cpp(1547): error: no suitable constructor exists to convert from
"long long" to "mmx_t"
  static mmx_t fix_108n184      = (long long)0xcf04cf04cf04cf04LL;
                                  ^
RTjpegN.cpp(3098): error: no suitable constructor exists to convert from
"unsigned long long" to "mmx_t"
   static mmx_t neg=(unsigned long long)0xffffffffffffffffULL;
                    ^
compilation aborted for RTjpegN.cpp (code 2)
make[2]: *** [RTjpegN.o] Error 2
make[2]: Leaving directory `/home/mark/mythtv/MC-icc/libs/libmythtv'
make[1]: *** [sub-libmythtv] Error 2
make[1]: Leaving directory `/home/mark/mythtv/MC-icc/libs'
make: *** [sub-libs] Error 2

I don't have enough experience with mmx and the mythtv code to correct
this error.  Does anyone have ideas on what needs to be done?  I think
the expected performance advantage of icc is worth a significant amount
of work.  Thanks.

Mark Rickard

-------------- next part --------------
#
# $Id$
#
# qmake configuration for linux-g++
#

MAKEFILE_GENERATOR	= UNIX
TEMPLATE		= app
CONFIG			+= qt warn_on release incremental
QMAKE_INCREMENTAL_STYLE  = sublib

QMAKE_CC		= icc
QMAKE_LEX		= flex
QMAKE_LEXFLAGS		= 
QMAKE_YACC		= yacc
QMAKE_YACCFLAGS		= -d
QMAKE_CFLAGS		= -g -O3 -Ob2 -tpp6 -xK -ip -unroll -i_dynamic
QMAKE_CFLAGS_DEPS	= -M
#QMAKE_CFLAGS_WARN_ON	= -Wall
QMAKE_CFLAGS_WARN_ON	= -w
QMAKE_CFLAGS_WARN_OFF	= -w
QMAKE_CFLAGS_RELEASE	=
QMAKE_CFLAGS_DEBUG	= -g
QMAKE_CFLAGS_SHLIB	= -fPIC
QMAKE_CFLAGS_YACC	= -Wno-unused -Wno-parentheses
QMAKE_CFLAGS_THREAD	= -D_REENTRANT

QMAKE_CXX		= icc
QMAKE_CXXFLAGS		= $$QMAKE_CFLAGS
QMAKE_CXXFLAGS_DEPS	= $$QMAKE_CFLAGS_DEPS
QMAKE_CXXFLAGS_WARN_ON	= $$QMAKE_CFLAGS_WARN_ON
QMAKE_CXXFLAGS_WARN_OFF	= $$QMAKE_CFLAGS_WARN_OFF
QMAKE_CXXFLAGS_RELEASE	= $$QMAKE_CFLAGS_RELEASE
QMAKE_CXXFLAGS_DEBUG	= $$QMAKE_CFLAGS_DEBUG
QMAKE_CXXFLAGS_SHLIB	= $$QMAKE_CFLAGS_SHLIB
QMAKE_CXXFLAGS_YACC	= $$QMAKE_CFLAGS_YACC
QMAKE_CXXFLAGS_THREAD	= $$QMAKE_CFLAGS_THREAD

QMAKE_INCDIR		=
QMAKE_LIBDIR		=
#QMAKE_LIBDIR		= /opt/intel/compiler70/ia32/lib
QMAKE_INCDIR_X11	= /usr/X11R6/include
QMAKE_LIBDIR_X11	= /usr/X11R6/lib
QMAKE_INCDIR_QT		= $(QTDIR)/include
QMAKE_LIBDIR_QT		= $(QTDIR)/lib
QMAKE_INCDIR_OPENGL	= /usr/X11R6/include
QMAKE_LIBDIR_OPENGL	= /usr/X11R6/lib

QMAKE_LINK		= icc -g -O3 -Ob2 -tpp6 -xK -ip -unroll -i_dynamic
QMAKE_LINK_SHLIB	= icc -g -O3 -Ob2 -tpp6 -xK -ip -unroll -i_dynamic
QMAKE_LFLAGS		=
QMAKE_LFLAGS_RELEASE	=
QMAKE_LFLAGS_DEBUG	=
QMAKE_LFLAGS_SHLIB	= -shared
QMAKE_LFLAGS_PLUGIN	= $$QMAKE_LFLAGS_SHLIB
QMAKE_LFLAGS_SONAME	= -Wl,-soname,
QMAKE_LFLAGS_THREAD	=
QMAKE_RPATH		= -Wl,-rpath,

QMAKE_LIBS		=
#QMAKE_LIBS		= -lcprts -lcxa -lguide -lguide_stats -limf -lirc -lircmt -lompstub -lsvml -lunwind
QMAKE_LIBS_DYNLOAD	= -ldl
QMAKE_LIBS_X11		= -lXext -lX11 -lm
QMAKE_LIBS_X11SM	= -lSM -lICE
QMAKE_LIBS_NIS		= -lnsl
QMAKE_LIBS_QT		= -lqt
QMAKE_LIBS_QT_THREAD	= -lqt-mt
QMAKE_LIBS_OPENGL	= -lGLU -lGL -lXmu
QMAKE_LIBS_OPENGL_QT	= -lGL -lXmu
QMAKE_LIBS_THREAD	= -lpthread

QMAKE_MOC		= $(QTDIR)/bin/moc
QMAKE_UIC		= $(QTDIR)/bin/uic

QMAKE_AR		= ar cqs
QMAKE_RANLIB		=

QMAKE_TAR		= tar -cf
QMAKE_GZIP		= gzip -9f

QMAKE_COPY		= cp -f
QMAKE_MOVE		= mv -f
QMAKE_DEL_FILE		= rm -f
QMAKE_DEL_DIR		= rmdir
QMAKE_STRIP             = strip
-------------- next part --------------
--- MC/settings.pro	2003-02-19 13:27:17.000000000 -0500
+++ MC-icc/settings.pro	2003-02-19 13:20:36.000000000 -0500
@@ -15,6 +15,6 @@
 
 release {
         DEFINES += MMX
-        QMAKE_CXXFLAGS_RELEASE = -O6 -march=pentiumpro -fomit-frame-pointer -funroll-loops -fexpensive-optimizations
+#        QMAKE_CXXFLAGS_RELEASE = -O6 -march=pentiumpro -fomit-frame-pointer -funroll-loops -fexpensive-optimizations
 }
 
-------------- next part --------------
--- MC/libs/libmythtv/mmx.h	2002-05-03 23:28:07.000000000 -0500
+++ MC-icc/libs/libmythtv/mmx.h	2003-02-19 13:34:19.000000000 -0500
@@ -65,150 +65,8 @@
 	   5 if AMD MMX and 3DNow! instructions are supported
 	   0 if hardware does not support any of these
 	*/
-	register int rval = 0;
-
-	__asm__ __volatile__ (
-		/* See if CPUID instruction is supported ... */
-		/* ... Get copies of EFLAGS into eax and ecx */
-		"pushf\n\t"
-		"popl %%eax\n\t"
-		"movl %%eax, %%ecx\n\t"
-
-		/* ... Toggle the ID bit in one copy and store */
-		/*     to the EFLAGS reg */
-		"xorl $0x200000, %%eax\n\t"
-		"push %%eax\n\t"
-		"popf\n\t"
-
-		/* ... Get the (hopefully modified) EFLAGS */
-		"pushf\n\t"
-		"popl %%eax\n\t"
-
-		/* ... Compare and test result */
-		"xorl %%eax, %%ecx\n\t"
-		"testl $0x200000, %%ecx\n\t"
-		"jz NotSupported1\n\t"		/* CPUID not supported */
-
-
-		/* Get standard CPUID information, and
-		       go to a specific vendor section */
-		"movl $0, %%eax\n\t"
-		"cpuid\n\t"
-
-		/* Check for Intel */
-		"cmpl $0x756e6547, %%ebx\n\t"
-		"jne TryAMD\n\t"
-		"cmpl $0x49656e69, %%edx\n\t"
-		"jne TryAMD\n\t"
-		"cmpl $0x6c65746e, %%ecx\n"
-		"jne TryAMD\n\t"
-		"jmp Intel\n\t"
-
-		/* Check for AMD */
-		"\nTryAMD:\n\t"
-		"cmpl $0x68747541, %%ebx\n\t"
-		"jne TryCyrix\n\t"
-		"cmpl $0x69746e65, %%edx\n\t"
-		"jne TryCyrix\n\t"
-		"cmpl $0x444d4163, %%ecx\n"
-		"jne TryCyrix\n\t"
-		"jmp AMD\n\t"
-
-		/* Check for Cyrix */
-		"\nTryCyrix:\n\t"
-		"cmpl $0x69727943, %%ebx\n\t"
-		"jne NotSupported2\n\t"
-		"cmpl $0x736e4978, %%edx\n\t"
-		"jne NotSupported3\n\t"
-		"cmpl $0x64616574, %%ecx\n\t"
-		"jne NotSupported4\n\t"
-		/* Drop through to Cyrix... */
-
-
-		/* Cyrix Section */
-		/* See if extended CPUID level 80000001 is supported */
-		/* The value of CPUID/80000001 for the 6x86MX is undefined
-		   according to the Cyrix CPU Detection Guide (Preliminary
-		   Rev. 1.01 table 1), so we'll check the value of eax for
-		   CPUID/0 to see if standard CPUID level 2 is supported.
-		   According to the table, the only CPU which supports level
-		   2 is also the only one which supports extended CPUID levels.
-		*/
-		"cmpl $0x2, %%eax\n\t"
-		"jne MMXtest\n\t"	/* Use standard CPUID instead */
-
-		/* Extended CPUID supported (in theory), so get extended
-		   features */
-		"movl $0x80000001, %%eax\n\t"
-		"cpuid\n\t"
-		"testl $0x00800000, %%eax\n\t"	/* Test for MMX */
-		"jz NotSupported5\n\t"		/* MMX not supported */
-		"testl $0x01000000, %%eax\n\t"	/* Test for Ext'd MMX */
-		"jnz EMMXSupported\n\t"
-		"movl $1, %0:\n\n\t"		/* MMX Supported */
-		"jmp Return\n\n"
-		"EMMXSupported:\n\t"
-		"movl $3, %0:\n\n\t"		/* EMMX and MMX Supported */
-		"jmp Return\n\t"
-
-
-		/* AMD Section */
-		"AMD:\n\t"
-
-		/* See if extended CPUID is supported */
-		"movl $0x80000000, %%eax\n\t"
-		"cpuid\n\t"
-		"cmpl $0x80000000, %%eax\n\t"
-		"jl MMXtest\n\t"	/* Use standard CPUID instead */
-
-		/* Extended CPUID supported, so get extended features */
-		"movl $0x80000001, %%eax\n\t"
-		"cpuid\n\t"
-		"testl $0x00800000, %%edx\n\t"	/* Test for MMX */
-		"jz NotSupported6\n\t"		/* MMX not supported */
-		"testl $0x80000000, %%edx\n\t"	/* Test for 3DNow! */
-		"jnz ThreeDNowSupported\n\t"
-		"movl $1, %0:\n\n\t"		/* MMX Supported */
-		"jmp Return\n\n"
-		"ThreeDNowSupported:\n\t"
-		"movl $5, %0:\n\n\t"		/* 3DNow! and MMX Supported */
-		"jmp Return\n\t"
-
-
-		/* Intel Section */
-		"Intel:\n\t"
-
-		/* Check for MMX */
-		"MMXtest:\n\t"
-		"movl $1, %%eax\n\t"
-		"cpuid\n\t"
-		"testl $0x00800000, %%edx\n\t"	/* Test for MMX */
-		"jz NotSupported7\n\t"		/* MMX Not supported */
-		"movl $1, %0:\n\n\t"		/* MMX Supported */
-		"jmp Return\n\t"
-
-		/* Nothing supported */
-		"\nNotSupported1:\n\t"
-		"#movl $101, %0:\n\n\t"
-		"\nNotSupported2:\n\t"
-		"#movl $102, %0:\n\n\t"
-		"\nNotSupported3:\n\t"
-		"#movl $103, %0:\n\n\t"
-		"\nNotSupported4:\n\t"
-		"#movl $104, %0:\n\n\t"
-		"\nNotSupported5:\n\t"
-		"#movl $105, %0:\n\n\t"
-		"\nNotSupported6:\n\t"
-		"#movl $106, %0:\n\n\t"
-		"\nNotSupported7:\n\t"
-		"#movl $107, %0:\n\n\t"
-		"movl $0, %0:\n\n\t"
-
-		"Return:\n\t"
-		: "=a" (rval)
-		: /* no input */
-		: "eax", "ebx", "ecx", "edx"
-	);
+//	register int rval = 0;
+	register int rval = 1;
 
 	/* Return */
 	return(rval);
-------------- next part --------------
--- MC/libs/libmythtv/XJ.cpp	2003-02-05 14:46:51.000000000 -0500
+++ MC-icc/libs/libmythtv/XJ.cpp	2003-02-19 13:29:04.000000000 -0500
@@ -11,6 +11,8 @@
 #include <sys/shm.h>
 #include <math.h>
 
+#include <pthread.h>
+
 #include <iostream>
 using namespace std;
 


More information about the mythtv-dev mailing list