I am running this pthread-c++ program (gauss elimination) on my laptop to measure its runtime.
The program runs about 10 seconds in real but my output shows about 20 seconds. What is wrong with this program?
I used
g++ -pthread main.c
./a.out 32 2048
to run
#include <stdio.h>
#include <stdlib.h>
#include <ctime>
#include <cstdlib>
#include <pthread.h>
#include <iostream>
typedef float Type;
void mat_rand (Type**, int, int);
Type** mat_aloc (int, int);
void mat_free (Type**);
void mat_print (Type**, int, int);
void* eliminate(void*);
unsigned int n, max_threads, active_threads, thread_length;
Type** A;
int current_row;
struct args
{
int start;
int end;
};
typedef struct args argument;
void *print_message_function( void *ptr );
int main(int argc, char *argv[])
{
if (argc < 3)
{
printf ("Error!. Please Enter The Matrix Dimension and No. of Threads!\n");
return 0;
} else
{
n = atoi(argv[2]);
max_threads = atoi(argv[1]);
if (n > 4096)
{
printf ("The maximum allowed size is 4096!\n");
return 0;
}
if (max_threads > 32)
{
printf ("The maximum allowed Threads Count is 32!\n");
return 0;
}
}
A = mat_aloc(n , n+1);
mat_rand (A, n, n+1);
//mat_print (A, n, n+1);
std::clock_t start;
double exe_time;
start = std::clock();
pthread_attr_t attr;
pthread_attr_init(&attr);
argument* thread_args = new argument[max_threads];
pthread_t* thread = new pthread_t[max_threads];
for (int i=0; i<n-1; i++)
{
current_row = i;
if (max_threads >= n-i)
active_threads = n-i-1;
else
active_threads = max_threads;
thread_length = (n-i-1)/active_threads;
for (int j=0; j<active_threads-1; j++)
{
thread_args[j].start = i+1+j*thread_length;
thread_args[j].end = i+1+(j+1)*thread_length;
pthread_create( &thread[j], &attr, eliminate, (void*) &thread_args[j]);
}
thread_args[active_threads-1].start = i+1+(active_threads-1)*thread_length;
thread_args[active_threads-1].end = n-1;
pthread_create(&thread[active_threads-1], &attr, eliminate, (void*) &thread_args[active_threads-1]);
for (int j=0; j<active_threads; j++)
{
pthread_join(thread[j], NULL);
}
}
exe_time = (clock() - start) / (double) CLOCKS_PER_SEC;
printf("Execution time for Matrix of size %i: %f\n", n, exe_time);
//mat_print (A, n, n+1);
return 0;
}
void* eliminate(void* arg)
{
Type k, row_constant;
argument* info = (argument*) arg;
row_constant = A[current_row][current_row];
for (int i=info->start; i<=info->end; i++)
{
k = A[i][current_row] / row_constant;
A[i][current_row] = 0;
for (int j=current_row+1; j<n+1; j++)
{
A[i][j] -= k*A[current_row][j];
}
}
}
// matrix random values
void mat_rand (Type** matrix, int row, int column)
{
for (int i=0; i<row; i++)
for (int j=0; j<column; j++)
{
matrix[i][j] = (float)(1) + ((float)rand()/(float)RAND_MAX)*256;
}
}
// allocates a 2d matrix
Type** mat_aloc (int row, int column)
{
Type* temp = new Type [row*column];
if (temp == NULL)
{
delete [] temp;
return 0;
}
Type** mat = new Type* [row];
if (temp == NULL)
{
delete [] mat;
return 0;
}
for (int i=0; i<row; i++)
{
mat[i] = temp + i*column;
}
return mat;
}
// free memory of matrix
void mat_free (Type** matrix)
{
delete[] (*matrix);
delete[] matrix;
}
// print matrix
void mat_print (Type** matrix, int row, int column)
{
for (int i=0; i<row; i++)
{
for (int j=0; j<column; j++)
{
std::cout<< matrix[i][j] << "\t\t";
}
printf("\n");
}
printf(".................\n");
}
clock reports CPU time used. If you have 2 CPUs and run a thread on each one for 10 seconds, clock will report 20 seconds.
Related
I'm working on a coding assignment for a C++ class. When I run my program I seem to be dealing with a memory leakage issue, which is weird since I am NOT explicitly allocating any memory in my code. I ran the program under gdb, and it seems as though the program crashes when running the destructor for a Deck object. I tried stepping through the code, but I when I do so I end up in a host of .h files related to vectors. Then suddenly, it stops. I tried going to a TA for some help, but they seem to be as perplexed as I am on the issue.
# include <stdlib.h>
# include <time.h>
# include <iostream>
# include <vector>
# include <stdio.h>
using namespace std;
//function signatures
float bustProbability (const int);
class Deck
{
public:
//data members
vector <int> cardArray;
vector <int> wasteCards;
//constructor
Deck();
//methods
void shuffleDeck();
void populateDeckWithCards();
void removeCopyCards();
int dealCard();
int remainingCards();
void showCards();
};
void Deck::removeCopyCards() {
for (unsigned int i = 0; i < wasteCards.size(); i++) {
bool removedCopy = false;
for (unsigned int j = 0; j < cardArray.size() && removedCopy == false; j++) {
if (cardArray[j] == wasteCards[i]) {
cardArray.erase (cardArray.begin() + j - 1);
removedCopy = true;
}
}
}
}
int Deck::dealCard() {
if (remainingCards() > 0) {
int tmp = cardArray.back();
wasteCards.push_back(tmp);
cardArray.pop_back();
return tmp;
}
else {
populateDeckWithCards();
removeCopyCards();
shuffleDeck();
//shuffle method
int tmp = cardArray.back();
cardArray.pop_back();
return tmp;
}
}
void Deck::populateDeckWithCards() {
//populate regular cards into array
for (int i = 2; i <= 10; i++) {
for (int j = 0; j < 4; j++) {
cardArray.push_back(i);
}
}
//populate J, Q, K into array
for (int i = 0; i < 3; i++) {
for (int j = 0; j < 4; j++) {
cardArray.push_back(10);
}
}
//populating array with Aces... treating them as special case '100'
for (int i = 0; i < 4; i++) {
cardArray.push_back(100);
}
return;
}
void Deck::showCards() {
for (unsigned int i = 0; i < cardArray.size(); i++) {
cout << cardArray[i] << endl;
}
}
Deck::Deck() {
wasteCards.clear();
cardArray.clear();
populateDeckWithCards();
shuffleDeck();
}
void Deck::shuffleDeck() {
int n = cardArray.size();
for(int a = n-1; a > 0; a--) {
int min = 0;
int max = a;
int j = min + rand() / (RAND_MAX / (max-min + 1) + 1);
int tmp = cardArray[a];
cardArray[a] = cardArray[j];
cardArray[j] = tmp;
}
return;
}
int Deck::remainingCards() {
return cardArray.size();
}
class Player {
public:
//data members
vector <int> playerHand;
//constructor
Player();
//methods
bool isBust();
int count();
void hit(Deck&);
void stand();
bool muckHand();
void showHand();
};
Player::Player() {
playerHand.clear();
}
void Player::showHand() {
for (unsigned int i = 0; i < playerHand.size(); i++) {
cout << playerHand[i] << endl;
}
return;
}
int Player::count() {
int handCount = 0;
for (unsigned int i = 0; i < playerHand.size(); i++) {
if (playerHand[i] != 100)
handCount += playerHand[i];
else {
if (playerHand[i] == 100) {
if ((handCount) > 11) {
handCount += 1;
}
else
handCount += 10;
}
}
}
return handCount;
}
bool Player::isBust() {
if (count() > 21)
return true;
else
return false;
}
void Player::hit(Deck& d) {
playerHand.push_back(d.dealCard());
}
void Player::stand() {
return;
}
bool Player::muckHand() {
playerHand.clear();
return true;
}
float bustProbability (const int threshHold) {
int threshHoldReached = 0;
Deck myDeck;
Player myPlayer;
Player dealer;
for (int i = 0; i < 10000; i++) {
myPlayer.hit(myDeck);
dealer.hit(myDeck);
myPlayer.hit(myDeck);
dealer.hit(myDeck);
while (myPlayer.count() < threshHold) {
myPlayer.hit(myDeck);
}
if (!(myPlayer.isBust())) {
++threshHoldReached;
}
myDeck.wasteCards.clear();
myPlayer.muckHand();
dealer.muckHand();
}
float bustFraction = float(threshHoldReached)/float(10000);
return bustFraction;
}
int main () {
cout << "blackjack simulation" << endl;
srand((unsigned int)time(NULL));
cout << bustProbability(19);
return 0;
}
I'm incredibly sorry for just posting my code, but I've spend 4 days on this issue, and I can't even begin to figure out what the problem is.
There is at least the line
cardArray.erase (cardArray.begin() + j - 1);
which seems to be dubious in case of j = 0
I'm writing a program for my algorithmic math class at university and I'm using Win 7 (x64), Eclipse Oxygen.1a Release (4.7.1a) with MinGW 6.3.0.
Whenever I build and run the program it crashes with windows claiming 'Abgabe3.exe stopped working' but when trying to find the problem using the debugger and breakpoints I step trough the whole program and it finishes without errors...
I stripped everything not used by the problematic function and copied everything into a seperate file and the exact problem occurs.
Maybe somebody has a clue what happened at my side. ^^
#include <math.h> /* pow, sqrt */
#include <iostream> /* cin, cout */
#include <new> /* new */
#include <string> /* string */
#include <stdlib.h> /* srand, rand */
#include <time.h> /* time */
using namespace std;
void NORM(double* res, double* x, int n){
res[0] = 0.0;
for(int i = 0; i < n; i++){
res[0] += pow(x[i], 2);
}
res[0] = sqrt(res[0]);
}
void initRand(double* x, int n){
srand (time(NULL) * rand());
for(int i = 0; i < n; i++){
x[i] = (((double) rand()) / ((double) RAND_MAX));
}
}
void createArray(double* &x, int n){
if (n > 0){
x = new double[n];
initRand(x, n);
}
}
void printArray(double* x, int n){
if (x != NULL){
cout<<"(\n";
for(int i = 0; i < n; i++){
if(i+1 == n) cout<<x[i];
else if ((i % 5) == 0) cout<<x[i];
else if ( ((i+1) % 5) == 0 ){
cout<<", "<<x[i]<<"\n";
}
else {
cout<<", "<<x[i];
}
}
cout<<"\n)\n";
}
else cout<<"\nError: pointer = NULL\n";
}
unsigned long long int bin(unsigned int n, unsigned int k){
unsigned long long res = 1;
if(k == 0) return 1;
else if( n >= k){
for(unsigned long long int i = 1; i <= k; i++){
res *= (n + 1 - i) / i;
}
}
else return 0;
return res;
}
void newArray(double** x, unsigned int v, unsigned int n){
for(unsigned int i = 0; i < v; i++){
double* ptr = x[i];
createArray(ptr,n);
x[i] = ptr;
}
}
void experiment(double** vektorArray){
unsigned int n = 10, v = 20;
cout<<"Dimension n = "<<n<<"\nAnzahl Versuche v = "<<v<<endl;
//Erstellen der Vektoren
cout<<"Erstellen - starte\n";
vektorArray = new double*[n];
newArray(vektorArray, v, n);
cout<<"Erstellen - fertig\n";
for(unsigned int i = 0; i < v; i++){
if(i%10 == 0) printArray(vektorArray[i], n);
}
}
int main(int argc, char** argv){
double** vektorArray = NULL;
experiment(vektorArray);
return 0;
}
vektorArray = new double*[n];
created an array of size n, but
void newArray(double** x, unsigned int v, unsigned int n)
{
for (unsigned int i = 0; i < v; i++)
{
double* ptr = x[i];
createArray(ptr, n);
x[i] = ptr;
}
}
and
for (unsigned int i = 0; i < v; i++)
{
if (i % 10 == 0)
printArray(vektorArray[i], n);
}
index that array with v. Looks like you got your variables crossed. Strongly recommend giving variables better, more descriptive names to help make this more obvious.
I have declared the following:
const int NUMBER_OF_DIGITS = 16;
std::vector<int> digits(NUMBER_OF_DIGITS);
However when I open the MSVC debugger it shows the following:
This is how I added values to the vector:
for (int i = 0; i < NUMBER_OF_DIGITS; ++i) {
scanf("%d", &digits[i]);
}
Is this normal? Can I just ignore this? Or is this a problem?
Full code(the program is still not ready yet):
#include <iostream>
#include <vector>
#include "stdio.h"
const int NUMBER_OF_DIGITS = 16;
int checksum, tmp1, tmp2, tmp3, sum = 0;
std::vector<int> digits(NUMBER_OF_DIGITS);
std::vector<int> new_digits(NUMBER_OF_DIGITS);
int luhn_checksum(std::vector<int> cardnumber[NUMBER_OF_DIGITS]) {
//step 1: duouble every second number
for (int i = 1; i < NUMBER_OF_DIGITS; i += 2) {
new_digits[i] = digits[i] * 2;
if (new_digits[i] > 9) {
//if the product is larger than 9 we will add the two numbers together
//example: 9 * 2 = 18 so we will add 1 + 8 to get 9
tmp1 += new_digits[i] % 10;
new_digits[i] /= 10;
tmp1 = 0;
}
}
//step 2: sum all the values
for (int i = 0; i < NUMBER_OF_DIGITS; ++i) {
checksum += new_digits[i];
}
return checksum;
}
void get_card_numbers(void) {
for (int i = 0; i < NUMBER_OF_DIGITS; ++i) {
scanf("%d", &digits[i]);
}
}
void initialize(void) {
for (int i = 0; i < NUMBER_OF_DIGITS; ++i) {
digits.push_back(0);
new_digits.push_back(0);
}
}
int main() {
initialize();
get_card_numbers();
printf("checksum is: %d\n", luhn_checksum(&digits));
std::cout << digits.size() << std::endl;
int x; scanf("%d", &x);
return 0;
}
The constructor you're using for digits is setting the size by specifying the count. So after calling push_back you've just added another 16 to the vector. Use a different constructor that doesn't set the count.
int _tmain(int argc, _TCHAR* argv[])
{
const int NUMBER_OF_DIGITS = 16;
std::vector<int> digits(NUMBER_OF_DIGITS);
//std::vector<int> digits;
int digitsLen = digits.size();
// Here is 16
for (int i = 0; i < NUMBER_OF_DIGITS; ++i) {
digits.push_back(0);
}
int digitsLen2 = digits.size();
// Here is 32
return 0;
}
Cleaned up your code a bit:
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
static const size_t NUMBER_OF_DIGITS = 16;
class cards {
public:
cards();
void read();
int luhnChecksum() const;
private:
vector<int> digits;
};
cards::cards() : digits(NUMBER_OF_DIGITS, 0)
{
}
void cards::read() {
for_each(digits.begin(), digits.end(), [](int& i) { cin >> i; });
}
int cards::luhnChecksum() const {
vector<int> newdigits(digits.begin(), digits.end());
for (size_t i=1; i<NUMBER_OF_DIGITS; i += 2) {
newdigits[i] = digits[i] * 2;
if (newdigits[i] > 9) {
int tmp1 = newdigits[i] % 10;
newdigits[i] /= 10;
newdigits[i] += tmp1;
}
}
return accumulate(newdigits.begin(), newdigits.end(), 0);
}
int main() {
cards c;
c.read();
cout << "checksum = " << c.luhnChecksum() << endl;
return 0;
}
I have an assignment where i need to use a matrix class of type T elements. I have a constructor using 2 int, one copy constructor, one constructor using a string and a destructor. matrix A uses first constructor and works fine, matrix B uses second and also prints out fine but i have an issue with matrix C. If I a declare it by itself(removing matrix a and b from main) it prints as well, but when all is there, it prints out something like:
3735748 3745176
3745176 3735748
(instead of
5 6
7 8)
And numbers change everytime I compile.
I feel like this should be obvious but i'm a beginner and cant figure it out.. Any help welcome! Thank you
template <class T>
class matrice
{
private :
unsigned int nLignes; //number of rows
unsigned int nColonnes; //nbr of cols
T** rep;
public :
matrice( unsigned int nl, unsigned int nc)
{
setLignes(nl);
setColonnes(nc);
rep = new T*[nl];
for(int i = 0; i < nl; i++){
rep[i] = new T[nc];
}
for(int i = 0; i < nl; i++){
for(int j = 0; j < nc; j++){
rep[i][j] = (T) i*j;
}
}
}
matrice( const matrice& mat)// my copy constructor
{
setLignes(mat.nLignes);
setColonnes(mat.nColonnes);
rep = new T*[nLignes];
for(int i = 0; i < nLignes; i++){
rep[i] = new T[nColonnes];
}
for(int i = 0; i < nLignes; i++){
for(int j = 0; j < nColonnes; j++){
rep[i][j] = (T) i*j;
}
}
}
matrice( const std::string& UnString)//constructor using a string
//"nl,nc,val1, val2.."
{
std::vector<int> vect;
std::stringstream ss(UnString);
int i;
while (ss >> i)
{
vect.push_back(i);
if (ss.peek() == ',')
ss.ignore();
}
setLignes(vect.at(0));
setColonnes(vect.at(1));
int taille = nLignes * nColonnes;
vect.erase(vect.begin(), vect.begin()+2);
if(taille == vect.size()){ // making sure enough values to
//fill array
int n = 0;
for(int i = 0; i < nLignes; i++){
rep[i] = new T[nColonnes];
}
for(int i = 0; i < nLignes; i++){
for(int j = 0; j < nColonnes; j++){
rep[i][j] = vect.at(n);
n++;
}
}
}
}
~matrice()
{
delete[] rep;
}
void afficher();//printing function
void setLignes(int l)
{
nLignes = l;
}
void setColonnes(int c)
{
nColonnes = c;
}
};
template <class T>
void matrice<T>::afficher()//printing function
{
int i,j;
for (i=0;i < nLignes;i++)
{
for(j=0;j < nColonnes;j++)
{
cout << rep[i][j] << " ";
}
cout << "\n";
}
}
/*
*
*MAIN*
******/
int main(int argc, char *argv[])
{
matrice <unsigned int> mat(5,3);//MATRIX A
matrice <unsigned int> a = mat;
a.afficher();
{
matrice <unsigned int> mat(6,6);//MATRIX B
matrice <unsigned int> b = mat;
b.afficher();
}
matrice <unsigned int> c("2,2,5,6,7,8");//MATRIX C !! problem
c.afficher();
system("pause");
return 0;
}
You forget allocate space for rep in the constructor using a string.
Moreover, your deconstructor is at risk of memory leaking, please check it yourself.
I have written a binary search like following. When I try to find 10, it's not showing me the result. What am I missing??
// BinarySearch.cpp : Defines the entry point for the console application.
//
#include "stdafx.h"
#include <iostream>
using namespace std;
void BinarySearch(int arr[],int value);
int * insertionshot(int arr[]);
int _tmain(int argc, _TCHAR* argv[])
{
int arr[10] = {1,2,3,10,5,9,6,8,7,4};
int value;
cin >> value ;
static int *ptr;// = new int[10];
ptr = insertionshot(arr);
BinarySearch(ptr,value);
return 0;
}
int * insertionshot(int arr[])
{
int ar[10];
for(int i =0;i < 10; i++)
{
ar[i] = arr[i];
}
int arrlength = sizeof(ar)/sizeof(ar[0]);
for(int a = 1; a <= arrlength -1 ;a++)
{
int b = a;
while(b > 0 && ar[b] < ar[b-1])
{
int temp;
temp = ar[b-1];
ar[b-1] = ar[b];
ar[b] = temp;
b--;
}
}
return ar;
}
void BinarySearch( int a[],int value)
{
int min,max,middle;
min = 0;
int ar[10];
for(int i =0;i < 10; i++)
{
ar[i] = a[i];
}
//printf("size of array = %d",sizeof(arr));
max = (sizeof(ar)/sizeof(ar[0]) -1);
middle = (min+max)/2;
while(min <= max)
{
if(ar[middle] == value)
{
cout << "The value found" << ar[middle];
break;
}
else if(ar[middle] < value)
{
min = middle +1;
}
else if(ar[middle] > value)
{
max = middle-1;
}
middle = (min+max)/2;
}
}
Finally i made it work,I think this code does not have any problem.This could help any one
// BinarySearch.cpp : Defines the entry point for the console application.
//
#include "stdafx.h"
#include <iostream>
using namespace std;
void BinarySearch(int arr[],int value);
int * insertionshot(int arr[],int);
int _tmain(int argc, _TCHAR* argv[])
{
int arr[10] = {1,2,3,10,5,9,6,8,7,4};
int * arr1 = new int[10];
for(int i = 0;i< sizeof(arr)/sizeof(arr[0]);i++)
{
arr1[i] = arr[i];
}
int value;
cin >> value ;
int *ptr = new int[10];
ptr = insertionshot(arr1,10); // address of sorted array will be returned.
BinarySearch(ptr,value);
arr1 = 0;
ptr =0;
delete arr1;
delete ptr;
return 0;
}
int * insertionshot(int arr1[],int n)
{
for(int a = 1; a <= n -1 ;a++)
{
int b = a;
while(b > 0 && arr1[b] < arr1[b-1])
{
int temp;
temp = arr1[b-1];
arr1[b-1] = arr1[b];
arr1[b] = temp;
b--;
}
}
return arr1;
}
void BinarySearch( int a[],int value)
{
int min,max,middle;
min = 0;
int ar[10];
for(int i =0;i < 10; i++)
{
ar[i] = a[i];
}
max = (sizeof(ar)/sizeof(ar[0]) -1);
middle = (min+max)/2;
while(min <= max)
{
if(ar[middle] == value)
{
cout << "The value found" << ar[middle];
break;
}
else if(ar[middle] < value)
{
min = middle +1;
}
else if(ar[middle] > value)
{
max = middle-1;
}
middle = (min+max)/2;
}
}
You're missing the most important part of a binary search: The collection you search in must be sorted.
For binary search, the array should be arranged in ascending or descending order.