Delete the first group of consecutive negative
elements in the array.
void delNegative(int* arr, int& size) {
if (!check_prop(arr, size, neg)) return;
int ind_l, ind_f;//
if (arr[0] < 0) ind_f = 0;
if (arr[size - 1] < 0) ind_l = size - 1;
for (int i = 1; i < size; i++){
if (arr[i - 1] > 0 && arr[i] < 0) ind_f = i;
if (arr[i - 1] < 0 && arr[i] > 0) ind_l = i - 1;
}
if (ind_l < ind_f) ind_l = size - 1;
int ii = 0;
for (int i = 0; i < size; i++)
if (i > ind_l || i < ind_f) {
arr[ii] = arr[i];
ii++;
}
size -= ind_l - ind_f + 1;
}
There is this function, but it removes the last group of negative elements.
It needs to be redone for dynamic arrays
I am required to display the execution time of some searching algorithms. However, when I use start/end_t = clock(), it always displays 0.00000 due to low precision (even with double-type)
Please tell me how to display those running times.
int LinearSearch (int M[], int target, int size)
{
int k = 0;
for (k=0; k<size; k++)
{
if(M[k]==target)
{
return k;
}
//else return -1;
}
}
int LinearSentinelSearch (int M[],int target, int size)
{
int k = 0;
M[size]=target;
while (M[k] != target)
k++;
return k;
}
int binSearch(int List[], int Target, int Size)
{
int Mid;
int low = 0;
int high = Size -1;
int count=0;
int a;
while( low <= high)
{
Mid = (low + high) / 2;
if(List[Mid] == Target) return Mid;
else if( Target < List[Mid] )
high = Mid - 1;
else
low = Mid + 1;
}
return -1;
}
You can calculate the mean execution time by simply executing the algorithm multiple times N and then divide the total time by N. Using your binSearch as an example:
int i;
clock_t start, end;
start = clock();
for (i = 0 ; i < 1000 ; i++) {
binSearch(/* your actual parameters here */);
}
end = clock();
printf("Mean ticks to execute binSearch: %f\n", (end - start) / 1000.0);
I'm doing my os homework, and the requirement is to implement parallel merge sort using Pthread and using semaphore to lock and unlock them.
You can only look at the function names Multi____ and ignore Single_____, because I've already finished the single thread part.
I encountered a problem in the multithreaded part. I signal the master thread (sem[1]) in line 227, and it should go into the function 'void *MultiPartition'.
In this function, it gives value to arg[id * 2] and arg[id * 2 + 1].
For example, arg[1] will gives value to arg[2] and arg[3], and then it signals thread[2] and thread[3] to start by sem_post.
And doesn't seem to work.
So I use cout << "partition id = " << id << ", head = " << head << ", mid = " << mid << ", tail = " << tail << "\n"; in line 111 to check out what happens.
It looks really weird. It sometimes outputs
partition id = 1, head = 0, mid = 7, tail = 15
partition id = 2, head = 0, mid = 3, tail = 7
and it was stuck, but the program didn't exit. Means I need to press Ctrl^C to exit program.
Sometimes it outputs
partition id = 1, head = 0, mid = 7, tail = 15
partition id = 2, head = 0, mid = 3, tail = 7
partition id = 3, head = 8, mid = 11, tail = 15
partition id = 4, head = 0, mid = 1, tail = 3
and was stuck, too.
I'm curious where other threads going?
And if id = 4 is displayed, it will runs bubble id = 8 usually.
#include <iostream>
#include <pthread.h>
#include <semaphore.h>
#include <fstream>
#include <sys/time.h>
#include <unistd.h>
using namespace std;
//Pthread_create, pthread_exit *don't use pthread_join
//sem_init, sem_wait, sem_post, sem_getvalue, sem_destroy
//Enter input file name: test.txt
//MT sorting used x secs
//ST sorting used x secs
// g++ -o os_hw3.out os_hw3.cpp -pthread
typedef struct{
int head;
int mid;
int tail;
int id;
}arguments;
//declare global variables
sem_t sem[16]; // use id = 1 ~ 15
sem_t final; // the final semaphore signal that indicate all threads finished.
int* s1, * s2; // two array for single and multiple
arguments arg[16];
void swap(int* x, int* y) {
int temp;
temp = *x;
*x = *y;
*y = temp;
}
void *MultiMerge(void* argid) {
int id = *(int*)argid;
sem_wait(&sem[id]);
sem_wait(&sem[id]);
int head = arg[id].head, mid = arg[id].mid, tail = arg[id].tail;
//cout << "merge id = " << id << ", head = " << head << ", mid = " << mid << ", tail = " << tail << "\n";
int lenA = mid - head + 1;
int lenB = tail - (mid + 1) + 1;
int A[lenA];
int B[lenB];
for (int i = 0; i < lenA; i++) {
A[i] = *(s1 + head + i);
}
for (int j = 0; j < lenB; j++) {
B[j] = *(s1 + mid + 1 + j);
}
int i = 0, j = 0, k = 0;
while (i < lenA && j < lenB) {
if (A[i] < B[j]) {
*(s1 + head + k) = A[i];
i++;
}
else {
*(s1 + head + k) = B[j];
j++;
}
k++;
}
while (i < lenA) {
*(s1 + head + k) = A[i];
i++;
k++;
}
while (j < lenA) {
*(s1 + head + k) = B[j];
j++;
k++;
}
sem_post(&sem[id / 2]); // signal the upper level
if (id == 1) {
fstream fout;
fout.open("output1.txt", ios::out);
for (i = 0; i < arg[1].tail + 1; i++)
fout << *(s2 + i);
fout.close();
sem_post(&final);
}
}
void *MultiBubble(void *argid) {
int id = *(int*)argid;
sem_wait(&sem[id]);
//cout << "bubble id = " << id << ", head = " << arg[id].head << ", tail = " << arg[id].tail << "\n";
for (int i = arg[id].tail; i > 0; --i) {
for (int j = arg[id].head; j < i; ++j) {
if (*(s2 + j) > * (s2 + j + 1)) {
swap((s2 + j), (s2 + j + 1));
}
}
}
for (int i = arg[id].head; i <= arg[id].tail; i++) {
cout << *(s2 + i) << " ";
}
cout << "\n";
sem_post(&sem[id / 2]);
}
void *MultiPartition(void* argid) {
int id = *(int*)argid;
sem_wait(&sem[id]);
int head = arg[id].head, mid = arg[id].mid, tail = arg[id].tail;
cout << "partition id = " << id << ", head = " << head << ", mid = " << mid << ", tail = " << tail << "\n";
arg[id * 2].head = arg[id].head;
arg[id * 2].tail = arg[id].mid;
arg[id * 2].mid = (arg[id * 2].head + arg[id * 2].tail) / 2;
arg[id * 2 + 1].head = arg[id].mid + 1;
arg[id * 2 + 1].tail = arg[id].tail;
arg[id * 2 + 1].mid = (arg[id * 2 + 1].head + arg[id * 2 + 1].tail) / 2;
sem_post(&sem[id * 2]);
sem_post(&sem[id * 2 + 1]);
}
void SingleMerge(int* s1, int head, int mid, int tail) {
int lenA = mid - head + 1;
int lenB = tail - (mid + 1) + 1;
int A[lenA];
int B[lenB];
for (int i = 0; i < lenA; i++) {
A[i] = *(s1 + head + i);
}
for (int j = 0; j < lenB; j++) {
B[j] = *(s1 + mid + 1 + j);
}
int i = 0, j = 0, k = 0;
while (i < lenA && j < lenB) {
if (A[i] < B[j]) {
*(s1 + head + k) = A[i];
i++;
}
else {
*(s1 + head + k) = B[j];
j++;
}
k++;
}
while (i < lenA) {
*(s1 + head + k) = A[i];
i++;
k++;
}
while (j < lenA) {
*(s1 + head + k) = B[j];
j++;
k++;
}
}
int SingleBubble(int* s1, int head, int tail) {
for (int i = tail; i > 0; --i) {
for (int j = head; j < i; ++j) {
if (*(s1 + j) > *(s1 + j + 1)) {
swap((s1 + j), (s1 + j + 1));
}
}
}
}
void SinglePartition(int* s1, int head, int tail, int times) {
if (head <= tail) {
int mid = (head + tail) / 2;
if (times < 3) {
SinglePartition(s1, head, mid, ++times);
SinglePartition(s1, mid + 1, tail, ++times);
}
else {
SingleBubble(s1, head, tail);
}
SingleMerge(s1, head, mid, tail);
}
}
int main() {
char filename[100];
int num;
struct timeval Tstart, Tend;
cout << "Enter the input file name: ";
cin >> filename;
fstream file, fout;
file.open(filename, ios::in);
if (!file) {
cout << "Read File Error.\n";
return -1;
}
else {
file >> num;
s1 = new int[num];
s2 = new int[num];
for (int i = 0; i < num; i++) {
file >> *(s1 + i);
*(s2 + i) = *(s1 + i);
}
file.close();
}
//SINGLE THREAD
gettimeofday(&Tstart, 0);
SinglePartition(s1, 0, num - 1, 0);
gettimeofday(&Tend, 0);
fout.open("output2.txt", ios::out);
for (int i = 0; i < num; i++)
fout << *(s1 + i) << " ";
fout.close();
double Tdifference = (Tend.tv_sec - Tstart.tv_sec) + (Tend.tv_usec - Tstart.tv_usec) / 1000000.0;
cout << "Single thread cost " << Tdifference << " s\n";
//MULTI THREAD
gettimeofday(&Tstart, 0);
arg[1].head = 0;
arg[1].tail = num - 1;
arg[1].mid = (arg[1].head + arg[1].tail) / 2;
pthread_t thread[16];
sem_init(&final, 0, 0);
sem_post(&sem[1]);
for (int i = 1; i < 16; i++){
arg[i].id = i;
sem_init(&sem[i], 0, 0);
if (i < 8) {
if(i == 1)
sem_post(&sem[1]); // call the master thread
pthread_create(&thread[i], NULL, MultiPartition, &arg[i].id);
}
else
pthread_create(&thread[i], NULL, MultiBubble, &arg[i].id);
}
for (int i = 7; i > 0; i--) {
pthread_create(&thread[i], NULL, MultiMerge, &arg[i].id);
}
sem_wait(&final);
gettimeofday(&Tend, 0);
Tdifference = (Tend.tv_sec - Tstart.tv_sec) + (Tend.tv_usec - Tstart.tv_usec) / 1000000.0;
cout << "Multi thread cost " << Tdifference << " s\n";
delete s1, s2;
for (int i = 0; i < 16; i++)
sem_destroy(&sem[i]);
sem_destroy(&final);
return 0;
}
I fixed it myself.
for (int i = 7; i > 0; i--) {
pthread_create(&thread[i], NULL, MultiMerge, &arg[i].id);
}
The above part will confront the following part.
for (int i = 1; i < 16; i++){
arg[i].id = i;
sem_init(&sem[i], 0, 0);
if (i < 8) {
if(i == 1)
sem_post(&sem[1]); // call the master thread
pthread_create(&thread[i], NULL, MultiPartition, &arg[i].id);
}
MultiMerge and MultiPartition both have
sem_wait(&sem[id]);
So if sem[id]'s value != 0, it doesn't know which function to do, in my opinion.
I delete
for (int i = 7; i > 0; i--) {
pthread_create(&thread[i], NULL, MultiMerge, &arg[i].id);
}
and add
MultiMerge(&arg[id].id);
in the bottom of MultiPartition to call MultiMerge, this can fixed my problem.
I have more or less the same question as
linux time command resulting real is less than user
and
user time larger than real time
but can't post a comment on those questions.
When I run the non-multi-threaded program given below, I occasionally get user time greater than real time with both /usr/bin/time and bash's builtin time. I don't see anything that might use a different core. Is rand() somehow the culprit? How? Thanks!
#include <stdio.h>
#include <stdlib.h>
#define N 100
#define MM_MAX 50000
int
main(int ac, char **av)
{
unsigned int i, j, k, n;
int A[N][N], B[N][N], C[N][N];
if (ac != 2) {
fprintf(stderr, "Usage: matmul <seed>");
exit(1);
}
srand((unsigned int) atoi(av[1]));
for (n = 0; n < atoi(av[1]); n++) {
for (i = 0; i < N; i++) {
for (j = 0; j < N; j++) {
A[i][j] = rand() % MM_MAX;
B[i][j] = rand() % MM_MAX;
}
}
for (i = 0; i < N; i++) {
for (j = 0; j < N; j++) {
C[i][j] = 0;
for (k = 0; k < N; k++) {
C[i][j] += A[i][k] * B[k][j];
}
printf("%7d ", C[i][j]);
}
putchar('\n');
}
}
return 0;
}
My code compiles but throws the following exception:
An unhandled exception of type 'System, Access Violation Exception' occured Additional Information: Attempted to read or write protected memory. . .
the error is related to s=s+a[z][r]*b[f][h]
Here a copy of the code:
#include"stdafx.h"
#include"iostream"
using namespace std;
int main()
{
int **a, **b;
int z, r, f, h, a_r, a_c, b_r, b_c, s = 0;
cout << "Enter the size of the matrix(nxm) :" << endl;
cin >> a_r >> a_c;
cout << "enter the size of the mask :" << endl;
cin >> b_r >> b_c;
a = (int **) malloc(10 * a_r);
for (int i = 0; i < a_c; i++)
{
a[i] = (int *) malloc(10 * a_c);
}
b = (int **) malloc(10 * b_r);
for (int i = 0; i < b_c; i++)
{
b[i] = (int *) malloc(10 * b_c);
}
for (int i = 0; i < a_r; i++)
{
for (int j = 0; j < a_c; j++)
{
a[i][j] = i + j;
}
}
for (int i = 0; i < b_r; i++)
{
for (int j = 0; j < b_c; j++)
{
b[i][j] = i + j;
}
}
int k = 1, d = 1;
for (int i = 0; i < a_r; i++)
{
for (int j = 0; j < a_c; j++)
{
for (int n = -1; n <= 1; n++)
{
for (int e = -1; e <= 1; e++)
{
z = i + n;
r = j + e;
f = k + n;
h = d + e;
if (z < 0 || z > a_r || r < 0 || r > a_c)
{
s = s + 0;
} else {
s = s + a[z][r] * b[f][h]; // runtime error occurs here
}
}
}
a[i][j] = s;
s = 0;
}
}
return 0;
}
Here is one problem:
if (z < 0 || z > a_r || r < 0 || r > a_c)
This should read:
if (z < 0 || z >= a_r || r < 0 || r >= a_c)
Otherwise you're potentially accessing out-of-bounds elements.