CMS 3D CMS Logo

SoATuple Class Reference

#include <FWCore/Utilities/interface/SoATuple.h>


Detailed Description

Description: Structure of Arrays Tuple

Usage: Often we want to group data which are related to one item and then group related items. This is often done by making a structure,Foo, to hold the data related to one item and then place the structure into a container (e.g. std::vector<Foo>). This is referred to as an 'Array of Structures'. However, this grouping can be inefficient if not all of the data about one item are used at the same time. So to access one data for one item will cause the CPU to retrieve nearby memory which is then not used. If the code is looking at the same data for multiple items this will lead to many data cache misses in the CPU.

A different grouping is to place the first data element for all items into one array, the second data element for all items into a second array, then so on. This is referred to as a 'Structure of Arrays'.

This class will take an arbitrary number of template arguments and it will group data of that argument type together in memory.

Example: Data about one item is represented by a double, int and bool

One can then push data into the collection. You must insert all data for each item.

    s.push_back(std::make_tuple(double{3.14},int{5},false));
    s.emplace_back(double{90.},int{0},true);

It is best if you call 'reserve' before pushing or emplacing items into the container in order to minimize memory allocations.

You get the data out by specify the 'ordinal' of the data element as well as the index

    double v = s.get<0>(1); //this return 90.
\encode

It is possible to loop over a data element for all items in the collection
\code
    for(auto it = s.begin<1>(), itEnd=s.end<1>(); it != itEnd; ++it) {
      std::cout<<*it<<" ";
    }
    //This returns '5 0 '
\encode
 
This template arguments for this class are not limited to simple builtins, any type can be used:
\code
    edm::SoATuple<std::string, ThreeVector> sComplex;

To help keep track of the purpose of the template arguments, we suggest using an enum to denote each one:

    enum {kPx,kPy,kPz};
    edm::SoATuple<double,double,double> s3Vecs;
    ...
    if(s.3Vecs.get<kPx>(i) > s.3Vecs.get<kPy>(i)) { ... }

A non-default alignment for a stored type can be specified by using the edm::Aligned<T,I> where I is an unsigned int value denoting the requested byte alignment. There is also a specialized version, edm::AlignedVec which has the proper alignment for SSE operations (16 byte aligned).

which is equivalent to

    edm::SoATuple<edm::AlignedVec<float>,edm::AlignedVec<float>,edm::AlignedVec<float>> vFloats;

Explicitly aligned types and defaultly aligned types can be freely mixed in any order within the template arguments.