text: Darryl Gove's blog
  putc in a multithreaded context
  Just answering a question from a colleague. The application was running significantly slower when compiled as a multithreaded app compared to the original serial app. The profile showed mutex_unlock as being hot, but going up the callstack the routine that called
  mutex_unlock was
  putc.
  This is the OpenSolaris source for putc, which shows a call to FLOCKFILE, which is defined in this file for MT programs. So for MT programs, a lock needs to be acquired before the character can be output.
  Fortunately it is possible to avoid the locking using
  putc_unlocked. This call should not be used as a drop-in replacement for putc, but used after the appropriate mutex has been acquired. The details are in the Solaris Multi-threaded programming guide.
  A test program that demonstrates this problem is:
  #include <stdio.h> #include <pthread.h> #include <sys/time.h> static double s_time; void starttime() { s_time=1.0*gethrtime(); } void endtime(long its) { double e_time=1.0*gethrtime(); printf("Time per iteration %5.2f ns\n", (e_time-s_time)/(1.0*its)); s_time=1.0*gethrtime(); } void *dowork(void *params) { starttime(); FILE* s=fopen("/tmp/dldldldldld","w"); for (int i=0; i<100000000; i++) { putc(65,s); } fclose(s); endtime(100000000); } void main() { starttime(); FILE* s=fopen("/tmp/dldldldldld","w"); for (int i=0; i<100000000; i++) { putc(65,s); } fclose(s); endtime(100000000); pthread_t threads[1]; pthread_create(&threads[0],NULL,dowork,NULL); pthread_join(threads[0],NULL); }
  Here's the results of running the code on Solaris 10:
  $ cc -mt putc.c Time per iteration 30.55 ns Time per iteration 165.76 ns
  The situation on Solaris 10 is better than Solaris 9, since on Solaris 9 the cost of the mutex was incurred by the
  -mt compiler flag rather than whether there were actually multiple threads active.
  Posted at 03:13PM Jan 07, 2008 by Darryl Gove in Sun |