From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 23734 invoked by alias); 28 Jul 2010 18:17:04 -0000 Received: (qmail 23724 invoked by uid 22791); 28 Jul 2010 18:17:03 -0000 X-SWARE-Spam-Status: No, hits=-2.0 required=5.0 tests=AWL,BAYES_00,DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,FREEMAIL_FROM,RCVD_IN_DNSWL_NONE X-Spam-Check-By: sourceware.org Received: from mail-ww0-f51.google.com (HELO mail-ww0-f51.google.com) (74.125.82.51) by sourceware.org (qpsmtpd/0.43rc1) with ESMTP; Wed, 28 Jul 2010 18:16:57 +0000 Received: by wwc33 with SMTP id 33so102843wwc.8 for ; Wed, 28 Jul 2010 11:16:54 -0700 (PDT) MIME-Version: 1.0 Received: by 10.216.169.80 with SMTP id m58mr10970922wel.79.1280341014532; Wed, 28 Jul 2010 11:16:54 -0700 (PDT) Received: by 10.216.133.84 with HTTP; Wed, 28 Jul 2010 11:16:54 -0700 (PDT) In-Reply-To: <824586E7387D1443B5DD024DAC75B91C139049@SE000319.ztb.icb.commerzbank.com> References: <824586E7387D1443B5DD024DAC75B91C139048@SE000319.ztb.icb.commerzbank.com> <824586E7387D1443B5DD024DAC75B91C139049@SE000319.ztb.icb.commerzbank.com> Date: Wed, 28 Jul 2010 18:17:00 -0000 Message-ID: Subject: Re: optimization question: mpl From: Piotr Rak To: "Hite, Christopher" Cc: Richard Guenther , gcc@gcc.gnu.org Content-Type: text/plain; charset=ISO-8859-1 Content-Transfer-Encoding: quoted-printable X-IsSubscribed: yes Mailing-List: contact gcc-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Id: List-Archive: List-Post: List-Help: Sender: gcc-owner@gcc.gnu.org X-SW-Source: 2010-07/txt/msg00406.txt.bz2 Hi, 2010/7/28 Hite, Christopher : >> Generally without knowing the compiler version you are using >> it is hard to tell. > I'll use whatever's best. =A0Right now I'm still on 4.4.3. =A0I'll probab= ly > upgrade soon to 4.5. > >> The same is true without a complete compilable testcase. > I didn't want to make a test case that depends on boost::mpl. How's > this: > > struct DecodeContext; > > struct M1{ > =A0 =A0 =A0 =A0static const int id=3D1; > =A0 =A0 =A0 =A0static void decode(DecodeContext& ){} > }; > > struct M2{ > =A0 =A0 =A0 =A0static const int id=3D2; > =A0 =A0 =A0 =A0static void decode(DecodeContext& ){} > }; > > struct M3{ > =A0 =A0 =A0 =A0static const int id=3D3; > =A0 =A0 =A0 =A0static void decode(DecodeContext& ){} > }; > > > template struct ListMember; > > template <> struct ListMember<1>{ typedef M1 type; }; > template <> struct ListMember<2>{ typedef M2 type; }; > template <> struct ListMember<3>{ typedef M3 type; }; > > template > void foo(int id, DecodeContext& dc) { > =A0 =A0 =A0 =A0typedef typename ListMember::type M; > =A0 =A0 =A0 =A0if(M::id=3D=3Did) > =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0M::decode(dc); > =A0 =A0 =A0 =A0else > =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0foo(id,dc); > } > > template<> > void foo<0>(int id, DecodeContext& dc) {} > > > > int main(){ > =A0 =A0 =A0 =A0DecodeContext& dc=3D *(DecodeContext*)0;// junk for now > =A0 =A0 =A0 =A0int id=3D2; //sometime runtime dependent > =A0 =A0 =A0 =A0foo<3>(id,dc); > =A0 =A0 =A0 =A0return 0; > } > > >> You can use the flatten attribute to tell the compiler to inline all >> calls in a given function, like >> >> void __attribute__((flatten)) foo(void) >> { >> ... >> decode1(); >> ... >> } > > That would cause decode1() to be inlined, which might not be what you > want. > > Hmm maybe I could rewrite things so the switch case returns a function > pointer. =A0I'm guessing that would make things slower though. > Or you could just initialize static array of pointers, like that (please note, that I never compiled code below): typedef void (*pfn) (DeclContext&); tempate struct InitDispatchHelper { static void init(std::tr1::array& a) { a[I-1] =3D ListMemeber::foo; InitPointersHelper::init(a); } }; // End recursion template<> struct InitDispatchHelper { static void init(std::tr1::array& a) { /*does nothing */ } }; // Dispatch table; template struct DispatchFoo : std::tr1::array { DispatchFoo() : std::tr1::array() { InitDispatchHelper::init(*this); } }; then your call would look like: static const int X =3D /* your maximal I in ListMembers meta-class */ void call_foo(int i, DeclContext& c) { static const DispatchFoo foo_dispatch; foo_dispatch[i] (c); } Bonus points for benchmarking both solutions and making it policy class choosing between those two solutions depending on X. Good luck, Piotr