I sequentially generate a number which then is looked up in an array which never change. Therefore it would be convenient if this array some how stays in the spawned threads cache.
unsigned int unordered_set[65535];
void init_set( unsigned int *a) {
...
}
unsigned int generate_number() {
...
}
unsigned int find_number(unsigned int a) {
unsigned int result=0;
#pragma omp parallel for
for(unsigned int i=0; i<65535;i++) {
if (unordered_set[i]==a)
result=i;
}
return result
}
void main() {
unsigned int x;
/* Fill the array with unique numbers */
init_set(unordered_set);
while(x>0) {
/*This loop can only be done sequentially */
x=generate_number();
unsigned int r=find_number(x);
if (r>0)
printf ("Found: %d %d",x,r);
}
}
I suppose that this never happens in the above code. Every time find_number is called the array unordered_set again and again is loaded into the threads caches. What can be done to ensure that the array stays in cache?
Related
#include <stdio.h>
#include <stdlib.h>
int smallest(int [],int);
int select_sort(int[],int);
int smallest(int arr[],int len){
int small_index=0;
int small=arr[0];
for(int i=0;i<len;i++){
if(arr[i]<small){small=arr[i];
small_index=i;
}
}
return small_index;
}
int select_sort(int arra[],int len){
int new_arra[100];
for(int i=0;i<len;i++){
int small=smallest(arra,len);
new_arra[i]=arra[small];
printf("%d",new_arra[i]);
}
return new_arra;
}
int main()
{
int arr[100]={6,1,0,-2,18};
select_sort(arr,5);
return 0;
}
I wrote this code for the selection sorting program and i know ideally i should be using the dynamic allocation for arrays in the select_sort function, but i was attempting it without it. It is supposed to print the array in an ascending order and I think I am messing up variable assignment somewhere, because when i run the program it only prints the smallest integer of the input array len number of times and not the rest of them.
If you don't mind messing up with your initial array, you can do:
int select_sort(int arra[],int len)
{
int maxValue = Integer.Max_Value;
int new_arra[100];
for(int i=0;i<len;i++){
int small=smallest(arra,len);
new_arra[i]=arra[small];
arra[small]= maxValue;
printf("%d",new_arra[i]);
}
return new_arra;
bear in mind that this is highly unefficient
i'm new to c. i'm writing a .h file dedicated to matrix. I want to write a function in .h file that returns a matrix (array) (not possible in c), so the real return is a pointer to a local array variable. But i can't use a local pointer in the main funct, so i've changed the int matrix[][] to static int matrix[][]. The problem now is: the user insert the number N of rows/columns, but a static array can only take a constant dimension. help
This is the .h
int N;
int i;
int j;
int *get_matrix(){
int user_input;
printf("set the dimension NxN of your matrix >> N=");
scanf("%d",&N );
static int temp_matrix[N][N];
for(i=0;i<N;i++){
for(j=0;j<N;j++){
printf("insert the matrix[%d][%d] value\n",i,j );
scanf("%d",&user_input);
temp_matrix[i][j]=user_input;
}
}
return temp_matrix;
}
void print_matrix(int *matrix){
for(i=0;i<sizeof(matrix)/4;i++){
for(j=0;j<sizeof(matrix)/4;j++){
printf("%7d",matrix[i][j]);
printf("\n");
}
}
}
this is the main.c file
#include <stdio.h>
#include "matrix_math.h"
void main(void){
int i;
int j;
int *p1 = get_matrix();
int matrix1[N][N];
for(i=0;i<N;i++){
for(j=0;j<N;j++){
matrix1[i][j]=p[i][j];
}
}
print_matrix(matrix1);
}
If this is just a school homework, and malloc not allowed/needed, and assuming it is acceptable to limit code to some reasonable upper limit N, consider defining matrix as a struct
#define MAXN 20
struct matrix {
int n ;
int data[MAXN][MAXN] ;
}
// matrix.c
struct matrix get_matrix() { ... ; return m } ;
void print_matrix(struct m *mp) {
for (int i = 0 ; i<mp->n ; i++) {
...
} ;
} ;
And then you can pass "matrix" around. Needless to say, better to pass matrix * whenever possible to improve performance. You can also make functions that return matrix, if needed.
This question already has answers here:
Getting a stack overflow exception when declaring a large array
(8 answers)
Closed 3 years ago.
How can I fix this code? I can't input a value for n more than 100000 but I have declared it as long long int.
I tried to solve it but couldn't. Please tell me what is wrong.
#include<stdio.h>
void main() {
long int n;
scanf("%ld",&n);
unsigned long long int a[n];
unsigned long long int max[n];
for(unsigned long long int i=0;i<n;i++) {
scanf("%lld",&a[i]);
}
for(unsigned long long int i=0;i<n;i++) {
unsigned long long int count=0;
for(unsigned long long int j=0;j<n;j++) {
if(a[i]==a[j]) {
count++;
}
}
max[i]=count;
}
for(unsigned long long int i=1;i<n;i++) {
if(max[0]<max[i]) {
max[0]=max[i];
a[0]=a[i];
}
else if(max[0]==max[i]) {
if(a[0]>a[i]) {
a[0]=a[i];
}
}
}
printf("%lld",a[0]);
}
You're declaring variables on the stack that are too big:
unsigned long long int a[n];
unsigned long long int max[n];
These variables are declared local to the function main, meaning that on most implementations they live on the stack. The stack is typically not that big, so when you specify a large value for n it creates arrays on the stack that are too big, overflowing the stack and causing a segfault.
Rather than creating the arrays on the stack, use malloc to create them on the heap:
unsigned long long int *a = malloc(n * sizeof(*a));
unsigned long long int *max = malloc(n * sizeof(*a));
Also, make sure you check the return value of malloc and call free when you're done.
We are given an array a[1..N]. For each element a[i] in the array, we note down the sum of all the elements which are smaller and occur before the present element. I need to calculate the total sum for every element in the array.
Constraints:
1<=N<=10^5
All elements will be between 0 and 10^6.
Here is the link to my question: http://www.spoj.com/problems/DCEPC206/. I'm using the approach shown below, but I'm getting TIME LIMIT EXCEEDED error on SPOJ. How can I improve my solution?
include
int main()
{
long n,a[100000],i,j,sum;
printf("enter the number of elements");
scanf("%ld",&n);
printf("enter the elements of the array");
for(i=0;i<n;i++)
scanf("%ld",&a[i]);
sum=0;
for(i=1;i<n;i++)
for(j=i-1;j>=0;j--)
if(a[i]>a[j])
sum+=a[j];
printf("\n%ld",sum);
return 0;
}
Yours is a trivial implementation which takes time of the order of O(n^2) but for the solution to get accepted you have to use Divide and Conquer as you do in Merge Sort which takes only O(NLogN) time compared to simpler sorting algorithms like Bubble Sort,etc.
For this you simply can change the Mergesort implementation a little bit simply by adding 2-3 lines of code in it. For understanding this better go through question of counting inversions in an array.(http://www.geeksforgeeks.org/counting-inversions/) Then you will realize you simply have to consider pairs opposite in nature to inversion and add all the smaller elements of all such pairs . For example - in an array 1,4,2,5 consider 4,2 is inversion but we have to consider pairs like 2,5 and 1,2 to get the solution. In every such pair keep adding the left no. ( Think hard about how it is doing our job !! )
For your reference go thoroughly through this merge sort code in which i have small changes to get a correct accepted solution.(sum variable stores the resultant value)
#include <stdio.h>
#include <stdlib.h>
long long int sum;
void merge(long long int c[],long long int arr[],long long int start,long long int middle,long long int end)
{
long long int i=0,j=start,k=middle;
while((j<middle)&&(k<end))
{
if(arr[j]<arr[k])
{
sum=sum+((end-k)*arr[j]);
c[i]=arr[j];
i++;j++;
}
else
{
c[i]=arr[k];
i++;k++;
}
}
while(j<middle)
{
c[i]=arr[j];
i++;
j++;
}
while(k<end)
{
c[i]=arr[k];
i++;
k++;
}
}
void msort(long long int arr[],long long int start,long long int end)
{
long long int middle=(start+end)/2;
if((end-start)==1)
{ return ;
}
msort(arr,start,middle);
msort(arr,middle,end);
long long int *c;
c=(long long int*)malloc(sizeof(long long int)*(end-start));
merge(c,arr,start,middle,end);
long long int i,j=0;
for(i=start;i<end;i++)
{
arr[i]=c[j];
j++;
}
}
void swap (long long int x[],long long int m,long long int n)
{
long long int t= x[m];
x[m]=x[n];
x[n]=t;
}
int main()
{
int t,i;
long long int n,*arr,j;
scanf("%d",&t);
for(i=0;i<t;i++)
{
scanf("%lld",&n);
arr = ( long long int * ) malloc ( sizeof(long long int) * n + 10);
for(j=0;j<n;j++)
{
scanf("%lld",&arr[j]);
}
sum=0;
msort(arr,0,n);
// for(j=0;j<n;j++)
// printf("%lld ",arr[j]);
printf("%lld\n",sum);
}
return 0;
}
Here i have written a code which produces next 8 numbers from sequence.
int next_exp_data(unsigned long long int expected_data)
{
int i=0;
unsigned long long int seq_gen_value=1976943448883713;
unsigned long long int temp_data[10];
temp_data[0]=seq_gen_value;
for(i=0;i<10;i++)
{
printf("%llu",temp_data[i]);
putchar('\n');
expected_data=temp_data[i];
temp_data[i+1]=temp_data[i] +2260630401189896;
}
return (expected_data);
}
I want to know how can i extract each byte/number of the array and return each number/byte ??Please help me out.
EDIT:Here's my code.Basically i want to read a file and compare the contents to check if the data read matches with generated sequential data.Here the buffer contains same data as temp_data is producing(ie 10 numbers like 0x07060504030201 next 0f0e0d0c0b0a0908 etc).I want to comapre buffer's data and the function's data.Can anyone suggest me how can i do.I am stuck.Any changes are appreciated.
#include<stdio.h>
#include<stdlib.h>
#include<inttypes.h>
int main(void){
FILE *fp;
char *buffer,c;
size_t filesize,buffer_size;
int i;
unsigned long long int expected_data=1976943448883713;
fp=fopen("seqdata.c","r");
if(fp==NULL){
fputs("Error\n",stderr);
exit(1);
}
fseek(fp,0L,SEEK_END);
filesize=ftell(fp);
printf("Size of seqdata file is:%u \n",filesize);
fseek(fp,0L,SEEK_SET);
buffer=(char*)malloc(sizeof(char)*filesize);
if(buffer == NULL){
fputs("\nMemory error ",stderr);
}
buffer_size=fread(buffer,sizeof(char),filesize,fp);
for(i=0;i<buffer_size;i++){
printf("%c",*(buffer +i));
}
printf("No of elements read from file are:%u \n",buffer_size);
fseek(fp,0L,SEEK_SET);
int current_pos = 0;
while(current_pos < buffer_size){
if(*(buffer +current_pos) != expected_data)
{
fputs("Error\n",stderr);
exit(1);
}
else{
printf("data matching \n");
current_pos++;
expected_data=next_exp_data(expected_data);
}
}
fclose(fp);
free(buffer);
return 0;
}
int next_exp_data(unsigned long long int expected_data)
{
int i=0;
unsigned long long int seq_gen_value=1976943448883713;
unsigned long long int temp_data[10];
temp_data[0]=seq_gen_value;
for(i=0;i<10;i++)
{
printf("%llu",temp_data[i]);
putchar('\n');
expected_data=temp_data[i];
temp_data[i+1]=temp_data[i] +2260630401189896;
}
return (expected_data);
}
It's machine dependent, but this usually works one of two ways:
union {
unsigned char b [8];
long long i;
} v;
v .i = seq_gen_value;
for (int j = 0; j < 8; ++j)
printf ("%d, ", v .b [j]);
On a little endian machine (x86, vax, etc.) the bytes come out with the least significant first. On a big endian machine, they come out with the most significant first.
By the way, it would be more useful to encode the "magic numbers" so that they can be more easily understood what they mean. For example, instead of 1976943448883713, write it as 0x7060504030201.
I think that your function do something like
return 1976943448883713 + 8 * 2260630401189896
And I think your question is not clear enough, like what array you want to return each its number? If you want to return array temp_data, it very easy. You can do that by
int next_exp_data(unsigned long long int expected_data, unsigned long long int temp_data[])
{
int i=0;
unsigned long long int seq_gen_value=1976943448883713;
temp_data[0]=seq_gen_value;
for(i=0;i<10;i++)
{
printf("%llu",temp_data[i]);
putchar('\n');
expected_data=temp_data[i];
temp_data[i+1]=temp_data[i] +2260630401189896;
}
return (expected_data);
}
Call this function with the second params is a array int with size 10.
And another thing, I don't think that this function need the 1st param, because it's not be used within the function, so you can remove that from functions params list
int next_exp_data( unsigned long long int temp_data[])
{
int i=0;
unsigned long long int expected_data;
unsigned long long int seq_gen_value=1976943448883713;
temp_data[0]=seq_gen_value;
for(i=0;i<10;i++)
{
printf("%llu",temp_data[i]);
putchar('\n');
expected_data=temp_data[i];
temp_data[i+1]=temp_data[i] +2260630401189896;
}
return expected_data; //dont use (expected_data), it will make things slower.
}
Comparing numbers in C is done using ==, !=, <= , >= , <, or >.
I didn't read your code as it's horrible formatted and doesn't seem relevant to your question as posed in the title.