C++Guns – RoboBlog

16.05.2018

C++ Guns: SIMD PointND

Filed under: Allgemein — Tags: — Thomas @ 10:05

Kommen wir wieder zurück zu meinem Lieblingsdatentype: PointND. Diesmal mit SSE. In den letzten Posts hab ich den Type SIMDarray vorgestellt zum gleichzeitigen prozessieren von mehreren Werten. Danach folge SIMDvalarray Type welcher arithmetische Operation +, -, *, /, definierte. Was braucht es noch mehr zum SIMD PointND? Eigentlich nichts. Ein PointND ist ein fixed size array der Länge N. Man kann noch ein paar Funktionen bereit stellen um explizit auf X und Y zuzugreifen. Aber das ist eigentlich nur Syntax Zucker und bringt keine neue Funktionalität. Also versuchen wir es:

template<typename Array>
struct PointND : Array {
  static_assert(Array().size() >= 2);
  using value_type = typename Array::value_type;

  const value_type& x() const {
    return (*this)[0];
  }

  const value_type& y() const {
    return (*this)[1];
  }
};

template<typename Array>
inline auto operator+(const PointND<Array>& lhs, const PointND<Array>& rhs) {
    return PointND<Array>{static_cast<Array>(lhs) + static_cast<Array>(rhs)};
}

template<typename Array>
auto func(const PointND<Array>& p1, const PointND<Array>& p2) {
    return (p1+p2).y();
}

auto func2(const PointND<SIMDvalarray<double, 2>>& p1, const PointND<SIMDvalarray<double, 2>>& p2) {
    return func(p1, p2);
}
acpl::func2(acpl::PointND<acpl::SIMDvalarray<double, 2ul> > const&, acpl::PointND<acpl::SIMDvalarray<double, 2ul> > const&):
  movapd (%rsi), %xmm0
  addpd (%rdi), %xmm0
  unpckhpd %xmm0, %xmm0

Also ein paar Sachen sind ja schon nervig. Zum einem die Templates. Für Funktionsargumente ist das zu verbose. Es zählt im Grunde nur, dass der Type ein PointND ist. Die Anzahl der Dimensionen, das zugrunde liegende Array oder value_type (int, double), spielt eigentlich keine Rolle. Der Compiler kennt den genauen Aufbau des Types und kann alles Nötige daraus Ableiten. Das selbe gilt auch für Point2D für nur 2D Funktionen. Hier müssten eigentlich Concepts weiter helfen....

Die zweite störende Sache sind die sich ständig wiederholenden operation+-*/ Funktionen. Weglassen kann man sie für PointND nicht. Es wird dann z.B. operator+ für SIMDvalarray aufgerufen, und das Ergebnis ist wieder ein SIMDvalarray, kein PointND. So ist dann der Zugriff auf Y wie im Code gezeigt nicht mehr möglich. Der Compiler ist so schlau zu erkennen, dass hier nur der Type geändert wird. Dies hat keinen Einfluss auf die Laufzeit, wie im Assembler Code zu sehen ist.

No Comments

No comments yet.

RSS feed for comments on this post.

Sorry, the comment form is closed at this time.

Powered by WordPress