Page 1 of 1

Small but significant speedup

Posted: 2012-02-13T23:34:10-07:00
by mailseth
Hi all, I was profiling my program, and I found that a small but significant chunk of time was spent in AcquirePixelCacheNexus() and DestroyPixelCacheNexus() (10%-20%) doing memory allocation. So I made the patch below and cut it down by quite a bit. I basically just reduce the malloc(), memset(), and free() calls. I tested the patch with 'make check' and it came back with no problems.

The code on my side is calling DrawPoint() thousands of times followed by MagickDrawImage(). This seems to be slow for just setting rows of pixels of varying transparency on the image. The multithreading doesn't seem to be assisting at all (only a single CPU is used among 16). Any help I could get in speeding it up would be great if I'm going about it wrong. :)
~Seth

Code: Select all

--- magick/cache.orig	2012-02-13 22:55:03.000000000 -0700
+++ magick/cache.c	2012-02-13 22:43:11.000000000 -0700
@@ -235,7 +235,9 @@
{
  NexusInfo
    **nexus_info;
-
+  NexusInfo
+    *nexus_info_arr;
+
  register ssize_t
    i;

@@ -243,12 +245,15 @@
    sizeof(*nexus_info));
  if (nexus_info == (NexusInfo **) NULL)
    ThrowFatalException(ResourceLimitFatalError,"MemoryAllocationFailed");
+
+    nexus_info_arr=(NexusInfo *)
AcquireQuantumMemory(number_threads,sizeof(**nexus_info));
+    if (nexus_info_arr == (NexusInfo *) NULL)
+       
ThrowFatalException(ResourceLimitFatalError,"MemoryAllocationFailed");
+    (void)
ResetMagickMemory(nexus_info_arr,0,number_threads*sizeof(*nexus_info_arr));
+
  for (i=0; i < (ssize_t) number_threads; i++)
  {
-    nexus_info[i]=(NexusInfo *)
AcquireQuantumMemory(1,sizeof(**nexus_info));
-    if (nexus_info[i] == (NexusInfo *) NULL)
-      ThrowFatalException(ResourceLimitFatalError,"MemoryAllocationFailed");
-    (void) ResetMagickMemory(nexus_info[i],0,sizeof(*nexus_info[i]));
+      nexus_info[i]=&(nexus_info_arr[i]);
    nexus_info[i]->signature=MagickSignature;
  }
  return(nexus_info);
@@ -1515,8 +1520,8 @@
    if (nexus_info[i]->cache != (PixelPacket *) NULL)
      RelinquishCacheNexusPixels(nexus_info[i]);
    nexus_info[i]->signature=(~MagickSignature);
-    nexus_info[i]=(NexusInfo *) RelinquishMagickMemory(nexus_info[i]);
  }
+    nexus_info[0]=(NexusInfo *) RelinquishMagickMemory(nexus_info[0]);
  nexus_info=(NexusInfo **) RelinquishMagickMemory(nexus_info);
  return(nexus_info);
}

Re: Small but significant speedup

Posted: 2012-02-14T06:03:49-07:00
by magick
Thanks for the speed-up suggestions.

For points you most promising speed up with points is to iterate over each pixel row and set the pixels that match your points bypassing the drawing methods. Alternatively you could grab each pixel that matches a point, update it with the pixel color for that point, then sync it back to the cache. Both of these methods should be lightning fast.