[Haskell-cafe] Re: Odd parallel haskell observations (some more numbers)

Alexander Kotelnikov sacha at myxomop.com
Mon Aug 9 06:42:05 EDT 2010


Hi.

>>>>> On Mon, 9 Aug 2010 09:44:00 +0200
>>>>> "JG" == Jean-Marie Gaillourdet <jmg at gaillourdet.net> wrote:
JG> 
JG> I am no expert in web server tuning, but I will share my thoughts
JG> about your approach and expectations nevertheless.

I would better think about ghc than about web server. I believe, that
numbers I already provided (especially their deviation) illustrate that
sometimes ghc runtime perform quite bad. 

I also found out that it can do better than it does by default, I can
accept that runtime might be not capable to adjust itself to any taks
the best way, but then it will be nice to know, for instance, why for
such I/O that GC settings change performance in times.

To illustrate even more that httpd has nothing to do with the phenomenon
I wrote a small C application which does pretty much the same. Numbers
tells that apache can serve much faster that it was required to please
haskell version (I will remind that it was 3.4 for single-threaded
haskell and went as low as 1.9s for 4-threaded). I attached the code
just in case.

10:27 sacha at loft4633:~/work/cube-server/tests 99> for i in 1 2 3 4; do for j in `seq 1 5`;do ./getc $i 10000;done;done
1 1.352978
1 1.348888
1 1.344545
1 1.345116
1 1.189060
2 0.668219
2 0.625113
2 0.698073
2 0.732621
2 0.722310
3 0.569121
3 0.581570
3 0.563512
3 0.566186
3 0.564232
4 0.510132
4 0.496181
4 0.529212
4 0.504506
4 0.511847

-------------- next part --------------
# include <stdio.h>
# include <pthread.h>
# include <sys/time.h>
# include <unistd.h>
# include <string.h>
# include <stdlib.h>

# include <sys/socket.h>
# include <netinet/in.h>
 #include <arpa/inet.h>

int fib(int n) {
  if ( n > 1 )
    return fib(n-1) + fib(n-2);
  else
    return 1;
}

# define REQ "GET / HTTP/1.1\r\n\r\n"

int get() {
  int s;
  int n;
  struct sockaddr_in sa;
  struct in_addr ia;
  char buf[10000];

  sa.sin_family = AF_INET;
  if ( !inet_pton(AF_INET, "127.0.0.1", &ia) ) {
    fprintf(stderr, "inet_pton\n");
    exit(1);
  }
  else {
    sa.sin_addr.s_addr = ia.s_addr;
  }
  sa.sin_port = htons(80);

  s = socket(AF_INET, SOCK_STREAM, 0);
  n = connect(s, (struct sockaddr*)&sa, sizeof(sa));

  send(s, REQ, strlen(REQ), 0);
  while ( (n = recv(s, buf, 10000, 0)) > 0 );
  //printf("%d\n", fib(38));
  close (s);
  return 0;
}

void* nget(void* p){
  int i;
  int n = *(int*)p;
  for ( i = 0; i < n; i++ )
    get();
  return NULL;
}

int main(int argc, char* argv[]) {
  int c;
  int n;
  int p;
  int i;
  double run_time;
  struct timeval start;
  struct timeval end;
  
  c = strtol(argv[1], NULL, 10);
  n = strtol(argv[2], NULL, 10);
  p = n/c;

  pthread_t *thread_ids;

  thread_ids = (pthread_t*)malloc(sizeof(pthread_t*) * c);

  gettimeofday(&start, NULL);
  for (i = 0; i < c; i++) {
    pthread_create(&thread_ids[i], NULL, nget, &p);
  }

  for (i = 0; i < c; i++) {
    pthread_join(thread_ids[i], NULL);
  }
  gettimeofday(&end, NULL);
  
  run_time = end.tv_sec - start.tv_sec + 1e-6 * (end.tv_usec - start.tv_usec);
  printf("%d %f\n", c, run_time);
  return 0;
}


More information about the Haskell-Cafe mailing list