Skip to content

Instantly share code, notes, and snippets.

@hugoppp
Last active December 20, 2022 14:04
Show Gist options
  • Save hugoppp/ac0aa524640b677a9c419bfce0c1f625 to your computer and use it in GitHub Desktop.
Save hugoppp/ac0aa524640b677a9c419bfce0c1f625 to your computer and use it in GitHub Desktop.
AOS vs SOA
#include <chrono>
#include <iostream>
#include <vector>
#include <numeric>
const int size = 8 * 1024 * 1024;
double average(std::vector<long> const &v) {
if (v.empty()) {
return 0;
}
return std::reduce(v.begin(), v.end()) / (double) v.size();
}
struct MyStruct {
int a,
b,
c,
d,
e,
f,
g,
h;
};
auto aos = new MyStruct[size];
auto aop = new MyStruct *[size];
struct SOA {
int a[size];
int b[size];
int c[size];
int d[size];
int e[size];
int f[size];
int g[size];
int h[size];
};
long testAOP();
long testAOS();
long testSOA();
auto soa = new SOA;
int main() {
std::vector<long> aop;
std::vector<long> aos;
std::vector<long> soa;
for (int i = 0; i < 20; i++) {
aop.push_back(testAOP());
aos.push_back(testAOS());
soa.push_back(testSOA());
}
std::cout << "AOP: " << average(aop) << std::endl;
std::cout << "AOS: " << average(aos) << std::endl;
std::cout << "SOA: " << average(soa) << std::endl;
}
long testSOA() {
std::chrono::steady_clock::time_point begin = std::chrono::steady_clock::now();
for (int i = 0; i < size; ++i) {
soa->a[i] = soa->a[i] + 1;
}
std::chrono::steady_clock::time_point end = std::chrono::steady_clock::now();
return std::chrono::duration_cast<std::chrono::milliseconds>(end - begin).count();
}
long testAOS() {
std::chrono::steady_clock::time_point begin = std::chrono::steady_clock::now();
for (int i = 0; i < size; ++i) {
aos[i].a = aos[i].a + 1;
}
std::chrono::steady_clock::time_point end = std::chrono::steady_clock::now();
return std::chrono::duration_cast<std::chrono::milliseconds>(end - begin).count();
}
long testAOP() {
long ms;
std::vector<char *> pointersToClear;
for (int i = 0; i < size; ++i) {
aop[i] = new MyStruct;
for (int k = 1; k < rand() % 15 + 1; k++)//simulate memory load
pointersToClear.push_back(new char[64]{});
}
for (const auto &item: pointersToClear)
delete[] item;
std::chrono::steady_clock::time_point begin = std::chrono::steady_clock::now();
for (int i = 0; i < size; ++i) {
aop[i]->a = aop[i]->a + 1;
}
std::chrono::steady_clock::time_point end = std::chrono::steady_clock::now();
ms = std::chrono::duration_cast<std::chrono::milliseconds>(end - begin).count();
for (int i = 0; i < size; ++i) {
delete aop[i];
}
return ms;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment