toon-members
[Top][All Lists]
Advanced

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

[Toon-members] General TooN aliasing problem


From: Ethan Eade
Subject: [Toon-members] General TooN aliasing problem
Date: Wed, 27 Aug 2008 01:39:02 +0100
User-agent: Thunderbird 2.0.0.12 (X11/20071114)

I've narrowed down the "bug" I had reported before to the test case below (without TooN), which shows that it's actually an aliasing problem, and that the compiler is entitled to get it "wrong". The problem is with the use of reinterpret_cast<> to change data access patterns (as in v.as_col() or m.T() or even matrix row access). The compiler doesn't know that two different access patterns are referring to the same memory, so the data dependencies aren't enforced, and the optimiser can put reads before the necessary writes that generate the data. Unfortunately, the compiler is not required to get these dependencies right. Using reinterpret_cast<> is saying "give me no guarantees about data dependencies". It was only a matter of time before the GCC optimiser got aggressive enough to trigger the behaviour.

I don't see an easy fix for this; it requires a redesign of TooN internals if optimisation is to be allowed.

- Ethan

This code gives bad output in gcc 4.3.1 with -O3, but not 4.2.1:
------------------------------
#include <iostream>
using namespace std;

template <int N> struct B;

template <int N>
struct A  // Vector
{
   double x[N];
const B<N>& as_B() const { return reinterpret_cast<const B<N>&>(*this); }
};

template <int N>
struct B // column Matrix
{
   double x[N][1];
const A<1>& row(int i) const {return reinterpret_cast<const A<1>&>(x[i][0]); }
};

template <int N>
ostream& operator<<(ostream& out, const A<N>& a)
{
   for (int i=0; i<N; ++i)
   out << a.x[i] << " ";
   return out;
}

template <int N>
ostream& operator<<(ostream& out, const B<N>& b)
{
   for (int i=0; i<N; ++i)
   out << b.row(i) << endl;
   return out;
}


int main()
{
   A<2> a;

   a.x[0] = 2;
   a.x[1] = 3;

   //cout << a.as_B().row(0).x[0] << endl << endl;  // (*)
// Gives wrong output if line (*) is commented
   cout << a.as_B() << endl;
}





reply via email to

[Prev in Thread] Current Thread [Next in Thread]