[C systemowe - Linux] optymalizacja kodu

0

Witam,

od niedawna, może nie do końca z własnej woli, staram się co nieco dowiedzieć o programowaniu w C pod Linuxem, coś tam piszę, coś kombinuję.

Ostatnio walczyłem z dwuprocesowym sortowaniem bąbelkowym. Sprawa wygląda tak: proces macierzysty tworzy losową tablicę o dowolnym rozmiarze, po czym jej połowę przesyła do procesu potomnego. zarówno jeden, jak i drugi sortują bąbelkowo swoje części, po czym potomek przesyła do macierzystego swoją posortowaną część. Macierzysty, mając jedną tablice, składającą się z dwóch posortowanych połówek zapuszcza na niej quicksorta.

Nie wnikając w powyższe założenia, potrzebuję pomocy w optymalizacji działania programu, ponieważ prowadzący zajęcia mówił, że już na poziomie 1000 elementów dwuprocesowe sortowanie będzie wydajniejsze niż jednoprocesowe sortowanie bąbelkowe. Sprawa wygląda tak, że u mnie na poziomie dopiero chyba 10000 elementów dwuprocesowe sortowanie jest szybsze.

Podejrzewam, że w znacznym stopniu opóźnienia wprowadza mi funkcja "sprintf" i "atoi" - obu ich używam, bo za cholerę przez pipe'a nie chce mi przejść przez pipe'a integer, a tylko stringi. Rzutowanie chyba też nie bardzo mi chciało działać, choć też już nie pamiętam, czy w obu przypadkach próbowałem (tzn. string -> int oraz int -> string(tzn. tablica char))

Poniżej zamieszczam kod programu. Wiem, że może proszę o zbyt wiele, ale mam nadzieję, że znajdzie się jakaś duszyczka chętna do pomocy ;)

double dwuprocsort(int rozmiar)
{
	int pid,p1[2],p2[2];
	double wynik=0;

	pipe(p1);
	pipe(p2);
	
	if((pid=fork())==0)
	{
		close(p1[1]);
		close(p2[0]);
		int i,j;
		int l_odbior=rozmiar/2;
		int tabsort[l_odbior];


		char buf[5];
		
		for(i=0;i<l_odbior;i++)
		{
			read(p1[0],buf,5);
			tabsort[i]=atoi(buf);
			//tabsort[i]=(int)buf;
		}
		
		int tmp;

		for(i=0;i<l_odbior-1;i++)
		{
			for(j=0;j<l_odbior-1;j++)
			{
				if(tabsort[j]>tabsort[j+1])
				{
					tmp=tabsort[j];
					tabsort[j]=tabsort[j+1];
					tabsort[j+1]=tmp;
				}
			}
		}

		for(i=0;i<l_odbior;i++)
		{
			sprintf(buf,"%d",tabsort[i]);
			write(p2[1],buf,5);
		}
		
		exit(3);
	}
	
	if(pid>0)
	{
		close(p1[0]);
		close(p2[1]);

		int t[rozmiar];
		int i,j,temp;
		double t1,t2,wynik;
		char posrednik[5];		
		struct timeval tv;
		
		srand(time(NULL));
		for(i=0;i<rozmiar;i++)
		{
			t[i]=(int)(rand()/(RAND_MAX+1.0)*10000.0);
		}
		
		int l_przekazania=rozmiar/2;
		int rozmiar2;

		if((rozmiar%2)==1)
			rozmiar2=l_przekazania+1;
		else
			rozmiar2=l_przekazania;

		gettimeofday(&tv, NULL);
		t1 = tv.tv_sec + 0.000001*tv.tv_usec;
		
		
		for(i=rozmiar2;i<l_przekazania+rozmiar2;i++)
		{
			sprintf(posrednik,"%d",t[i]);
			write(p1[1],posrednik,5);
		}

		for(i=0;i<rozmiar2-1;i++)
		{
			for(j=0;j<rozmiar2-1;j++)
			{
				if(t[j]>t[j+1])
				{
					temp=t[j];
					t[j]=t[j+1];
					t[j+1]=temp;
				}
			}
		}

		for(i=rozmiar2;i<rozmiar;i++)
		{
			read(p2[0],posrednik,5);
			t[i]=atoi(posrednik);
			//t[i]=(int)posrednik;
		}
		
		qsort(t,rozmiar,sizeof(int),rosnaco);
		
		gettimeofday(&tv, NULL);
		t2 = tv.tv_sec + 0.000001*tv.tv_usec;

		wynik=t2-t1;
		wait();
		return wynik;
		
	}
}
0

za cholerę przez pipe'a nie chce mi przejść przez pipe'a integer, a tylko stringi.

mi takie cos przechodzi bez problemu więc nie wiem z czym możesz mieć problem..


int p[2];
int buf[3];
pipe(p);

switch(fork())
{
case 0:
buf[0] = 10;
write(p[1], &buf, 3*sizeof(int));
exit(1);
break;

default :
read(p[0], &buf, 3*sizeof(int));
printf("%d %d %d\n",buf[0],buf[1],buf[2]);
wait();
break;
}
0

moze wiec uzyj socketpair()...

#include <sys/types.h>
#include <sys/socket.h>
#include <stdio.h>
#include <errno.h>

int main(){

  int sv[2];
  if(socketpair(AF_UNIX,SOCK_STREAM,0,sv)<0){
    printf("error\n");
    return -1;
  }
  int a=0x12345678;
  int b=0;

  printf("send: %d\n",send(sv[0],&a,sizeof(int),0));
  printf("recv: %d\n",recv(sv[1],&b,sizeof(int),0));

  printf("b=0x%x\n",b);


  close(sv[1]);
  close(sv[2]);
  return 0;
};

DOPISANE tak btw walnalem sie, powinno byc

  close(sv[0]);
  close(sv[1]);
0
klajter napisał(a)

za cholerę przez pipe'a nie chce mi przejść przez pipe'a integer, a tylko stringi.

mi takie cos przechodzi bez problemu więc nie wiem z czym możesz mieć problem..


int p[2];
int buf[3];
pipe(p);

switch(fork())
{
case 0:
buf[0] = 10;
write(p[1], &buf, 3*sizeof(int));
exit(1);
break;

default :
read(p[0], &buf, 3*sizeof(int));
printf("%d %d %d\n",buf[0],buf[1],buf[2]);
wait();
break;
}

zrobiłem jak napisałeś, oczywiście mój błąd - zapomniałem o ampersandzie (&) przed nazwą zmiennej z/do której odczytuję/zapisuje. dzięki za pomoc w tej kwestii :)

jednakże wyniki wciąż nie są zadowalające, poniżej zamieszczam czasy dla jednoprocesowego i dwuprocesowego sortowania:

Jednoprocesowe sortowanie babelkowe tablicy o wielkoci 10 elementów
                        Czas sortowania tablicy o wielkoci 10 elementów: 0.000005
Jednoprocesowe sortowanie babelkowe tablicy o wielkoci 100 elementów
                        Czas sortowania tablicy o wielkoci 100 elementów: 0.000070
Jednoprocesowe sortowanie babelkowe tablicy o wielkoci 1000 elementów
                        Czas sortowania tablicy o wielkoci 1000 elementów: 0.003655
Jednoprocesowe sortowanie babelkowe tablicy o wielkoci 10000 elementów
                        Czas sortowania tablicy o wielkoci 10000 elementów: 0.402732
Jednoprocesowe sortowanie babelkowe tablicy o wielkoci 25000 elementów
                        Czas sortowania tablicy o wielkoci 25000 elementów: 2.556501

Dwuprocesowe sortowanie babelkowe tablicy o wielkoci 10 elementów
                        Czas sortowania tablicy o wielkoci 10 elementów: 0.000055
Dwuprocesowe sortowanie babelkowe tablicy o wielkoci 100 elementów
                        Czas sortowania tablicy o wielkoci 100 elementów: 0.000336
Dwuprocesowe sortowanie babelkowe tablicy o wielkoci 1000 elementów
                        Czas sortowania tablicy o wielkoci 1000 elementów: 0.005717
Dwuprocesowe sortowanie babelkowe tablicy o wielkoci 10000 elementów
                        Czas sortowania tablicy o wielkoci 10000 elementów: 0.397243
Dwuprocesowe sortowanie babelkowe tablicy o wielkoci 25000 elementów
                        Czas sortowania tablicy o wielkoci 25000 elementów: 2.269536

dobre wyniki miałem, gdy skorzystałem z następującej konstrukcji:
write(p[1], &buf, dlugosc_tablicy_do_przekazania*sizeof(int));
analogicznie w read.

Wynikało to chyba z tego, że nie musiał pojedynczo przepychać tego, a raz całość. Problem polegał na tym, że wówczas przekazywane dane były.... że tak powiem z d**y wzięte. Jeszcze pokombinuję, ale Was oczywiście też proszę o pomoc ;)

@flabra, całość ma działać na pipe'ach, nie socket'ach. ale dzięki za sugestię ;)

1 użytkowników online, w tym zalogowanych: 0, gości: 1