112590Sjason@lowepower.com/* 212590Sjason@lowepower.com * Copyright (c) 2017 Jason Lowe-Power 312590Sjason@lowepower.com* All rights reserved. 412590Sjason@lowepower.com* 512590Sjason@lowepower.com* Redistribution and use in source and binary forms, with or without 612590Sjason@lowepower.com* modification, are permitted provided that the following conditions are 712590Sjason@lowepower.com* met: redistributions of source code must retain the above copyright 812590Sjason@lowepower.com* notice, this list of conditions and the following disclaimer; 912590Sjason@lowepower.com* redistributions in binary form must reproduce the above copyright 1012590Sjason@lowepower.com* notice, this list of conditions and the following disclaimer in the 1112590Sjason@lowepower.com* documentation and/or other materials provided with the distribution; 1212590Sjason@lowepower.com* neither the name of the copyright holders nor the names of its 1312590Sjason@lowepower.com* contributors may be used to endorse or promote products derived from 1412590Sjason@lowepower.com* this software without specific prior written permission. 1512590Sjason@lowepower.com* 1612590Sjason@lowepower.com* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 1712590Sjason@lowepower.com* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 1812590Sjason@lowepower.com* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 1912590Sjason@lowepower.com* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 2012590Sjason@lowepower.com* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 2112590Sjason@lowepower.com* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 2212590Sjason@lowepower.com* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 2312590Sjason@lowepower.com* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 2412590Sjason@lowepower.com* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 2512590Sjason@lowepower.com* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 2612590Sjason@lowepower.com* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 2712590Sjason@lowepower.com* 2812590Sjason@lowepower.com* Authors: Jason Lowe-Power 2912590Sjason@lowepower.com*/ 3012590Sjason@lowepower.com 3112590Sjason@lowepower.com#include <iostream> 3212590Sjason@lowepower.com#include <thread> 3312590Sjason@lowepower.com 3412590Sjason@lowepower.comusing namespace std; 3512590Sjason@lowepower.com 3612590Sjason@lowepower.com/* 3712590Sjason@lowepower.com * c = a + b 3812590Sjason@lowepower.com */ 3912590Sjason@lowepower.comvoid array_add(int *a, int *b, int *c, int tid, int threads, int num_values) 4012590Sjason@lowepower.com{ 4112590Sjason@lowepower.com for (int i = tid; i < num_values; i += threads) { 4212590Sjason@lowepower.com c[i] = a[i] + b[i]; 4312590Sjason@lowepower.com } 4412590Sjason@lowepower.com} 4512590Sjason@lowepower.com 4612590Sjason@lowepower.com 4712590Sjason@lowepower.comint main(int argc, char *argv[]) 4812590Sjason@lowepower.com{ 4912590Sjason@lowepower.com unsigned num_values; 5012590Sjason@lowepower.com if (argc == 1) { 5112590Sjason@lowepower.com num_values = 100; 5212590Sjason@lowepower.com } else if (argc == 2) { 5312590Sjason@lowepower.com num_values = atoi(argv[1]); 5412590Sjason@lowepower.com if (num_values <= 0) { 5512590Sjason@lowepower.com cerr << "Usage: " << argv[0] << " [num_values]" << endl; 5612590Sjason@lowepower.com return 1; 5712590Sjason@lowepower.com } 5812590Sjason@lowepower.com } else { 5912590Sjason@lowepower.com cerr << "Usage: " << argv[0] << " [num_values]" << endl; 6012590Sjason@lowepower.com return 1; 6112590Sjason@lowepower.com } 6212590Sjason@lowepower.com 6312590Sjason@lowepower.com unsigned cpus = thread::hardware_concurrency(); 6412590Sjason@lowepower.com 6512590Sjason@lowepower.com cout << "Running on " << cpus << " cores. "; 6612590Sjason@lowepower.com cout << "with " << num_values << " values" << endl; 6712590Sjason@lowepower.com 6812590Sjason@lowepower.com int *a, *b, *c; 6912590Sjason@lowepower.com a = new int[num_values]; 7012590Sjason@lowepower.com b = new int[num_values]; 7112590Sjason@lowepower.com c = new int[num_values]; 7212590Sjason@lowepower.com 7312590Sjason@lowepower.com if (!(a && b && c)) { 7412590Sjason@lowepower.com cerr << "Allocation error!" << endl; 7512590Sjason@lowepower.com return 2; 7612590Sjason@lowepower.com } 7712590Sjason@lowepower.com 7812590Sjason@lowepower.com for (int i = 0; i < num_values; i++) { 7912590Sjason@lowepower.com a[i] = i; 8012590Sjason@lowepower.com b[i] = num_values - i; 8112590Sjason@lowepower.com c[i] = 0; 8212590Sjason@lowepower.com } 8312590Sjason@lowepower.com 8412590Sjason@lowepower.com thread **threads = new thread*[cpus]; 8512590Sjason@lowepower.com 8612590Sjason@lowepower.com // NOTE: -1 is required for this to work in SE mode. 8712590Sjason@lowepower.com for (int i = 0; i < cpus - 1; i++) { 8812590Sjason@lowepower.com threads[i] = new thread(array_add, a, b, c, i, cpus, num_values); 8912590Sjason@lowepower.com } 9012590Sjason@lowepower.com // Execute the last thread with this thread context to appease SE mode 9112590Sjason@lowepower.com array_add(a, b, c, cpus - 1, cpus, num_values); 9212590Sjason@lowepower.com 9312590Sjason@lowepower.com cout << "Waiting for other threads to complete" << endl; 9412590Sjason@lowepower.com 9512590Sjason@lowepower.com for (int i = 0; i < cpus - 1; i++) { 9612590Sjason@lowepower.com threads[i]->join(); 9712590Sjason@lowepower.com } 9812590Sjason@lowepower.com 9912590Sjason@lowepower.com delete[] threads; 10012590Sjason@lowepower.com 10112590Sjason@lowepower.com cout << "Validating..." << flush; 10212590Sjason@lowepower.com 10312590Sjason@lowepower.com int num_valid = 0; 10412590Sjason@lowepower.com for (int i = 0; i < num_values; i++) { 10512590Sjason@lowepower.com if (c[i] == num_values) { 10612590Sjason@lowepower.com num_valid++; 10712590Sjason@lowepower.com } else { 10812590Sjason@lowepower.com cerr << "c[" << i << "] is wrong."; 10912590Sjason@lowepower.com cerr << " Expected " << num_values; 11012590Sjason@lowepower.com cerr << " Got " << c[i] << "." << endl; 11112590Sjason@lowepower.com } 11212590Sjason@lowepower.com } 11312590Sjason@lowepower.com 11412590Sjason@lowepower.com if (num_valid == num_values) { 11512590Sjason@lowepower.com cout << "Success!" << endl; 11612590Sjason@lowepower.com return 0; 11712590Sjason@lowepower.com } else { 11812590Sjason@lowepower.com return 2; 11912590Sjason@lowepower.com } 12012590Sjason@lowepower.com} 121