Part 1 : Memory Layout - Example answer
#include "workshop.h"
class People
{
public:
People(int npeople = 0)
{
if (npeople > 0)
{
height = workshop::Array<float>(npeople,0.0);
weight = workshop::Array<float>(npeople,0.0);
girth = workshop::Array<float>(npeople,0.0);
}
}
People(const workshop::Array<workshop::Person> &people)
{
height = workshop::Array<float>(people.size());
weight = workshop::Array<float>(people.size());
girth = workshop::Array<float>(people.size());
for (int i=0; i<people.size(); ++i)
{
height[i] = people[i].height;
weight[i] = people[i].weight;
girth[i] = people[i].girth;
}
}
workshop::Person operator[](int i) const
{
return workshop::Person(height[i], weight[i], girth[i]);
}
void set(int i, workshop::Person person)
{
height[i] = person.height;
weight[i] = person.weight;
girth[i] = person.girth;
}
workshop::Array<workshop::Person> toArray() const
{
workshop::Array<workshop::Person> people(height.size());
for (int i=0; i<height.size(); ++i)
{
people[i].height = height[i];
people[i].weight = weight[i];
people[i].girth = girth[i];
}
return people;
}
workshop::Array<float> height;
workshop::Array<float> weight;
workshop::Array<float> girth;
};
int main(int argc, char **argv)
{
const int npeople = 1024;
auto people = People(npeople);
//construct a random sample of people (in reality, you would
//read this from real data - here we are just randomly generating
//it using functions already provided in workshop.h
for (int i=0; i<npeople; ++i)
{
people.set(i, workshop::Person( workshop::getRandomHeight(),
workshop::getRandomWeight() ) );
}
auto timer = workshop::start_timer();
float avg_ratio = 0;
for (int j=0; j<100000; ++j)
{
avg_ratio = 0;
for (int i=0; i<npeople; ++i)
{
avg_ratio += (people.height[i] / people.weight[i]);
}
avg_ratio /= npeople;
}
auto duration = workshop::get_duration(timer);
timer = workshop::start_timer();
float vec_avg_ratio = 0;
for (int j=0; j<100000; ++j)
{
vec_avg_ratio = 0;
#pragma omp simd reduction(+:vec_avg_ratio)
for (int i=0; i<npeople; ++i)
{
vec_avg_ratio += (people.height[i] / people.weight[i]);
}
vec_avg_ratio /= npeople;
}
auto vector_duration = workshop::get_duration(timer);
std::cout << "The standard loop took " << duration
<< " microseconds to complete. The average ratio is "
<< avg_ratio << std::endl;
std::cout << "The vectorised loop took " << vector_duration
<< " microseconds to complete. The average ratio is "
<< vec_avg_ratio << std::endl;
return 0;
}