Structure of arrays and array of structures - performance difference

后端 未结 4 1639
情深已故
情深已故 2020-12-06 01:24

I have a class like this:

//Array of Structures
class Unit
{
  public:
    float v;
    float u;
    //And similarly many other variables of float type, upto         


        
相关标签:
4条回答
  • 2020-12-06 02:07

    Two things you should be aware that can made a huge difference, depending on your CPU:

    1. alignment
    2. cache line aliasing

    Since you are using SSE4, using a specialized memory allocation function that returns an address that aligned at a 16 byte boundary instead of new may give you a boost, since you or the compiler will be able to use aligned load and stores. I have not noticed much difference in newer CPUs, but using unaligned load and stores on older CPUs may be a little bit slower.

    As for cache line aliasing, Intel explicit mentions it on its reference manuals (search for "Intel® 64 and IA-32 Architectures Optimization Reference Manual"). Intel says it is something you should be aware, specially when using SoA. So, one thing you can try is to pad your arrays so the lower 6 bits of their addresses are different. The idea is to avoid having them fighting for the same cache line.

    0 讨论(0)
  • 2020-12-06 02:09

    Prefetches are critical to code that spends most of its execution time waiting for data to show up. Modern front side busses have enough bandwidth that prefetches should be safe to do, provided that your program isn't going too far ahead of its current set of loads.

    For various reasons, structures and classes can create numerous performance issues in C++, and may require more tweaking to get acceptable levels of performance. When code is large, use object-oriented programming. When data is large (and performance is important), don't.

    float v[N];
    float u[N];
        //And similarly many other variables of float type, up to 10-12 of them.
    //Either using an inlined function or just adding this text in main()
           v[j] += u[j];
           v[j] = v[j] * i[j] * t[j];
    
    0 讨论(0)
  • Certainly, if you don't achieve vectorization, there's not much incentive to make an SoA transformation.

    Besides the fairly wide de facto acceptance of __RESTRICT, gcc 4.9 has adopted #pragma GCC ivdep to break assumed aliasing dependencies.

    As to use of explicit prefetch, if it is useful, of course you may need more of them with SoA. The primary point might be to accelerate DTLB miss resolution by fetching pages ahead, so your algorithm could become more cache hungry.

    I don't think intelligent comments could be made about whatever you call "compile time" allocation without more details, including specifics about your OS. There's no doubt that the tradition of allocating at a high level and re-using the allocation is important.

    0 讨论(0)
  • 2020-12-06 02:22

    Structure of arrays is not cache friendly in this case.

    You use both u and v together, but in case of 2 different arrays for them they will not be loaded simultaneously into one cache line and cache misses will cost huge performance penalty.

    _mm_prefetch can be used to make AoS representation even faster.

    0 讨论(0)
提交回复
热议问题