Small but significant speedup

Questions and postings pertaining to the development of ImageMagick, feature enhancements, and ImageMagick internals. ImageMagick source code and algorithms are discussed here. Usage questions which are too arcane for the normal user list should also be posted here.
Post Reply
mailseth
Posts: 5
Joined: 2010-12-07T18:53:19-07:00
Authentication code: 8675308

Small but significant speedup

Post 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);
}
User avatar
magick
Site Admin
Posts: 11064
Joined: 2003-05-31T11:32:55-07:00

Re: Small but significant speedup

Post 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.
Post Reply