Last active
December 20, 2022 14:04
-
-
Save hugoppp/ac0aa524640b677a9c419bfce0c1f625 to your computer and use it in GitHub Desktop.
AOS vs SOA
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#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