how to reduce page faults in this program? - performance

I'm gating more then 1000 page faults in this program.
can i reduce them to some smaller value or even to zero ?
or even any other changes can speed up the execution
#include <stdio.h>
#include<stdlib.h>
int main(int argc, char* argv[])
{
register unsigned int u, v,i;
register unsigned int arr_size=0;
register unsigned int b_size=0;
register unsigned int c;
register unsigned int *b;
FILE *file;
register unsigned int *arr;
file=fopen(argv[1],"r");
arr=(unsigned int *)malloc(4*10000000);
while(!feof(file)){
++arr_size;
fscanf(file,"%u\n",&arr[arr_size-1]);
}
fclose(file);
b=(unsigned int *)malloc(arr_size*4);
if (arr_size!=0)
{
++b_size;
b[b_size-1]=0;
for (i = 1; i < arr_size; ++i)
{
if (arr[b[b_size-1]] < arr[i])
{
++b_size;
b[b_size-1]=i;
continue;
}
for (u = 0, v = b_size-1; u < v;)
{
c = (u + v) / 2;
if (arr[b[c]] < arr[i]) u=c+1; else v=c;
}
if (arr[i] < arr[b[u]])
{
b[u] = i;
}
if(i>arr_size)break;
}
}
free(arr);
free(b);
printf("%u\n", b_size);
return 0;
}

The line:
arr=(unsigned int *)malloc(4*10000000);
is not a good programming style. Are you sure that your file is as big as 40MBs? try not to allocate the whole memory in the first lines of your program.

Related

Why is my code printing symbols instead of letters?

I am supposed to write a program with three files (mysource.c, myMain.c, and mysource.h) to create a randomly generated string of characters. The length of the string is decided by the user. After the string is generated, the program will bump all letters in the string to the next letter in the alphabet to create a new offset string. I have most of the code sorted out, but my output is printing "╠╠╠╠". It prints the correct amount of characters but it is only printing those symbols. What do I need to do so that the characters print as actual letters rather than these symbols?
Here is my header file:
void generateChars(char *myarr, int len);
void offsetChars(char *myarr, int len);
void printChars(char *myarr, int len);
Here is my source code:
#include <stdio.h>
#include <stdlib.h>
#include "mysource.h"
void generateChars(char* myarr, int len)
{
int i = 0;
char letters[26] ={'a','b','c','d','e','f','g','h','i','j','k','l','m','n','o'
,'p','q','r','s','t','u','v','w','x','y','z' };
for (i = 0; i < len; i++);
{
myarr[i] = letters[rand() % 26];
}
}
//end generate function
void offsetChars(char *myarr, int len)
{
char i;
int j;
for (j = 0; j < len; j++)
{
for (i = 'a'; i <= 'z'; i++)
{
if (myarr[j] == i)
{
myarr[j] = i + 1;
break;
}
if (myarr[j] == 'z')
{
myarr[j] = 'a';
break;
}
}
}
}
//end offset function
void printChars(char *myarr, int len)
{
int i;
for (i = 0; i < len; i++)
{
printf("%c",myarr[i]);
}
}//end of print function
Here is my main code:
#include <stdio.h>
#include <stdlib.h>
#include "mysource.h"
int main()
{
int n;
printf("How many random characters do you want to
generate?: ");
scanf_s("%i", &n);
char myarr[1024];
printf("\nOriginal Combo:\n");
generateChars(&myarr, n);
printChars(&myarr, n);
printf("\nOffset Combo:\n");
offsetChars(&myarr, n);
printChars(&myarr, n);
return 0;
}
Here is the output I get:
I don't have enough reputation so this is the picture of the output
Yes there are two source codes, the objective is to make this assignment work with both source codes. Any help is appreciated!

Why does the left shift on a unsigned int happens from the 16th bit?

I am trying to put the values from the vector into the int.
Given vector :'1','0','1','1','1','0','1','1','1','0','1','1','1','0','1','1' :
Expected output (binary representation for the variable out):
00000000000000001011101110111011.
However, I am getting the following output:
10111011101110110000000000000000
Notice: the insertion begun at the 16bit from right end instead of beginning from the leftmost bit
#include<vector>
#include<iostream>
int main() {
std::vector<unsigned char> test = {'1','0','1','1','1','0','1','1','1','0','1','1','1','0','1','1'};
std::vector<unsigned int> out(1);
int j = 0;
for (int i =0; i < test.size(); i++) {
out[j] = out[j] << 1;
if (test[i] == '1') {out[j] |=0x1;}
}
j++;
for (int p = 0; p < j; p++) {
for (int k = 0; k<32; k++ ) {
std::cout << !!((out[p]<<k)&0x8000);
}
std::cout << std::endl;
}
std::cout << "Size Of:" << sizeof(int);
return 0;
}
The reason why this happens is that you are using a wrong constant for the mask: 0x8000 has its 16-bit set, while you probably meant to use 0x80000000 with the 32-nd bit set. To avoid mistakes like that it's best to construct masks with shifts, for example
(1 << 31)
This expression is evaluated at compile time, so the result is the same as if you computed the constant yourself.
Note that both 0x8000 and 0x80000000 constants are system-dependent. Moreover, 0x80000000 assumes 32-bit int, which is not guaranteed.
A better approach would be shifting the number right instead of left, and masking with 1.
The block of code creating out[j] works just fine.
Your problem is in the output block, due to use of 0x8000. Whenever k >= 16, the low 16 bits will be zero, guaranteeing that 0x8000 is zero.
Your code seems overly complicated to me. Here's my version of a C program that transforms a string of 1's and 0's into an int and one going from int to string.
#include <stdlib.h>
#include <stdio.h>
int main(int argc, char **argv);
int main (int argc, char **argv) {
char str [] = "1010101010101010";
int x;
int out;
for (x=0;x<16;x++) {
if (str[x] == '1') {
out |= (1 << x);
}
}
printf("%d", out) ;
}
and
#include <stdlib.h>
#include <stdio.h>
int main(int argc, char **argv);
int main (int argc, char **argv) {
char str [] = "1010101010101010";
int in = 21845;
char out[17] = {0};
for (x=0;x<16;x++) {
if (in & (1<<x)) {
out[x] = '1';
}
else {
out[x] = '0';
}
}
printf("%s", out) ;
}

quick select is not working for all indexes

I am trying to implement quick select referring to a algorithm given in the following link
http://www.cs.yale.edu/homes/aspnes/pinewiki/QuickSelect.html
But the program crashes for many k values, and works fine for only few. Kindly guide me where i am doing wrong.
#include <stdio.h>
#include <stdlib.h>
int a1[10];
int a2[10];
int quickselect(int a[], int k,int len){
int r = rand()%(len-1);
int pivot = a[r];
int i =0;
int len1=0,len2=0;
for(i=0 ;i<len;i++){
if(a[i]<pivot)
a1[len1++]=a[i];
else if(a[i]>pivot)
a2[len2++] = a[i];
else
continue;
}
if(k<=len1)
return quickselect(a1, k,len1);
else if (k > len-len2)
return quickselect(a2, k - (len-len2),len2);
return pivot;
}
int main()
{
int a[7] = {8,3,2,6,1,9,5};
int val = quickselect(a,3,7);
printf("%d \n",val);
return 0;
}
I have test your code. I think you should change int r = rand()%(len-1) to int r = rand()%len because when len==1you will get a floating point exception.

Run time comparison of Bubble sort and quick sort

I wish to do a run time comparison of two sorting algorithms- Bubble sot and Randomized Quick sort. My code works fine but I guess I am using some primitive techniques. The 'clock' calculations happen in int, so even if I try to get the time in micro seconds, I get something like 20000.000 micro seconds.
The code:
Bubblesort:
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#include <time.h>
int bubblesort(int a[], int n);
int main()
{
int arr[9999], size, i, comparisons;
clock_t start;
clock_t end;
float function_time;
printf("\nBuBBleSort\nEnter number of inputs:");
scanf("%d", &size);
//printf("\nEnter the integers to be sorted\n");
for(i=0;i<size;i++)
arr[i]= rand()%10000;
start = clock();
comparisons= bubblesort(arr, size);
end = clock();
/* Get time in milliseconds */
function_time = (float)(end - start) /(CLOCKS_PER_SEC/1000000.0);
printf("Here is the output:\n");
for(i=0;i<size ;i++)
printf("%d\t",arr[i]);
printf("\nNumber of comparisons are %d\n", comparisons);
printf("\nTime for BuBBle sort is: %f micros\n ", function_time);
return 0;
}
int bubblesort(int a[], int n)
{
bool swapped = false;
int temp=0, counter=0;
for (int j = n-1; j>0; j--)
{
swapped = false;
for (int k = 0; k<j; k++)
{
counter++;
if (a[k+1] < a[k])
{
//swap (a,k,k+1)
temp= a[k];
a[k]= a[k+1];
a[k+1]= temp;
swapped = true;
}
}
if (!swapped)
break;
}
return counter;
}
Sample Output:
BuBBleSort
Enter number of inputs:2000
Time for BuBBle sort is: 20000.000000 micros
Quicksort:
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
int n, counter=0;
void swap(int *a, int *b)
{
int x;
x = *a;
*a = *b;
*b = x;
}
void quicksort(int s[], int l, int h)
{
int p; /* index of partition */
if ((h- l) > 0)
{
p= partition(s, l, h);
quicksort(s, l, p- 1);
quicksort(s, p+ 1, h);
}
}
int partition(int s[], int l, int h)
{
int i;
int p; /* pivot element index */
int firsthigh; /* divider position for pivot element */
p= l+ (rand())% (h- l+ 1);
swap(&s[p], &s[h]);
firsthigh = l;
for (i = l; i < h; i++)
if(s[i] < s[h])
{
swap(&s[i], &s[firsthigh]);
firsthigh++;
}
swap(&s[h], &s[firsthigh]);
return(firsthigh);
}
int main()
{
int arr[9999],i;
clock_t start;
clock_t end;
float function_time;
printf("\nRandomized Quick Sort");
printf("\nEnter the no. of elements…");
scanf("%d", &n);
//printf("\nEnter the elements one by one…");
for(i=0;i<n;i++)
arr[i]= rand()%10000;
start = clock();
quicksort(arr,0,n-1);
end = clock();
/* Get time in milliseconds */
function_time = (float)(end - start) / (CLOCKS_PER_SEC/1000.0);
printf("\nCounter is %d\n\n", counter);
printf("\nAfter sorting…\n");
for(i=0;i<n;i++)
printf("%d\t",arr[i]);
printf("\nTime for Randomized Quick Sort is: %f ms\n", function_time);
return 0;
}
Sample Output:
Randomized Quick Sort
Enter the no. of elements…9999
Time for Randomized Quick Sort is: 0.000000 ms
As you can see, Quicksort doesn't show any run time with my technique even with a much larger input size than Bubblesort.
Could someone help in refining it with that part of run time comparison?
p.s.: The code is liberally borrowed from online sources
Try the follwoing code.
printf("Clock() %ld", clock());
sleep(1);
printf("\t%ld\n", clock());
my result is...
Clock() 6582 6637
gettimeofday(2) is better than clock(3). Because gettiemofday(2) store time in a struct
struct timeval {
time_t tv_sec; /* seconds */
suseconds_t tv_usec; /* microseconds */
};
Record start time and stop time, then you can get elapsed time in microseconds by the formula
(stop.tv_sec - start.tv_sec) * 1000000. + stop.tv_usec - start.tv_usec

MPI matrix multification compile err: undeclared with code

I coded a mpi matrix multification program, which use scanf("%d", &size), designate matrix size, then I defined int matrix[size*size], but when I complied it, it reported that matrix is undeclared. Please tell me why, or what my problem is!
According Ed's suggestion, I changed the matrix definition to if(myid == 0) block, but got the same err! Now I post my code, please help me find out where I made mistakes! thank you!
int size;
int main(int argc, char* argv[]) {
int myid, numprocs;
int *p;
MPI_Status status;
int i,j,k;
MPI_Init(&argc, &argv);
MPI_Comm_rank(MPI_COMM_WORLD,&myid);
MPI_Comm_size(MPI_COMM_WORLD, &numprocs);
if(myid == 0)
{
scanf("%d", &size);
int matrix1[size*size];
int matrix2[size*size];
int matrix3[size*size];
int section = size/numprocs;
int tail = size % numprocs;
srand((unsigned)time(NULL));
for( i=0; i<size; i++)
for( j=0; j<size; j++)
{
matrix1[i*size+j]=rand()%9;
matrix3[i*size+j]= 0;
matrix2[i*size+j]=rand()%9;
}
printf("Matrix1 is: \n");
for( i=0; i<size; i++)
{
for( j=0; j<size; j++)
{
printf("%3d", matrix1[i*size+j]);
}
printf("\n");
}
printf("\n");
printf("Matrix2 is: \n");
Reformatted code would be nice...
One problem is that you haven't declared the size variable. Another problem is that the [size] notation for declaring arrays is only good for sizes that are known at compile time. You want to use malloc() instead.
You don't actually need to define a MAX_SIZE if you use dynamic memory allocation.
#include <stdio.h>
#include <stdlib.h>
...
scanf("%d", &size);
int *matrix1 = (int *) malloc(size*size*sizeof(int));
int *matrix2 = (int *) malloc(size*size*sizeof(int));
int *matrix3 = (int *) malloc(size*size*sizeof(int));
...

Resources