#include <iostream> #include <iomanip> #include <vector> #include <chrono> using namespace std; // __attribute__ allows g++ to specify unique properties // In this case, it makes quadDouble a 16 byte vector typedef double quadDouble __attribute__((vector_size(32))); const int TEST_SIZE{1'000'000}; //const int TEST_SIZE{10}; int main() { vector<quadDouble> aS,bS; vector<double> aN, bN; srand(time(nullptr)); quadDouble entry; cout << "The size of the SWAR element is " << sizeof(entry[0]) << endl; cout << "The size of the NORMAL element is " << sizeof(double) << endl; cout << endl; for(int i = 0; i < TEST_SIZE; ++i) { for(int j =0; j < 4; ++j) { double x = static_cast<double>(rand())/RAND_MAX; entry[j] = x; aN.push_back(x); bN.push_back(x); } aS.push_back(entry); bS.push_back(entry); } auto start = chrono::steady_clock::now(); for(int i = 0; i < TEST_SIZE; ++i) { aS[i] = aS[i] + aS[i]; bS[i] = aS[i] * 2; aS[i] = bS[i] * aS[i]; aS[i] = bS[i] / 3.14159; } auto end = chrono::steady_clock::now(); auto duration = chrono::duration_cast<chrono::milliseconds>(end - start); cout << "Execution time SWAR: " << duration.count() << " ms" << endl; start = chrono::steady_clock::now(); for(int i = 0; i < TEST_SIZE*4; ++i) { aN[i] = aN[i] + aN[i]; bN[i] = aN[i] * 2; aN[i] = bN[i] * aN[i]; aN[i] = bN[i] / 3.14159; } end = chrono::steady_clock::now(); duration = chrono::duration_cast<chrono::milliseconds>(end - start); cout << "Execution time NORMAL: " << duration.count() << " ms" << endl; // cout << setprecision(20); bool hasError{false}; for(int i = 0; i < TEST_SIZE; ++i) { for(int j =0; j < 4; ++j) { // cout << setw(30) << aS[i][j] << setw(30) << aN[i*4+j] << endl; if (aS[i][j] != aN[i*4 + j] or bS[i][j] != bN[i*4+j]) { if (!hasError) { cout << "Error at i = " << i << " j = " << j << endl; hasError = true; i = TEST_SIZE; j = 4; } } } } return 0; }