Example Threads

From BoofCV
Revision as of 12:05, 12 July 2021 by Peter (talk | contribs)
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)
Jump to navigationJump to search

Support for concurrent algorithms (a.k.a. multi-threading) was added in BoofCV v0.33. Many low level image processing routines now have concurrent implementations and more are being planned. This example shows you how to control the threads and what sort of performance benefits you can expect. Go to the Concurrency page for more information on concurrency in BoofCV.

When you run the example you will see output like this, showing how performance improves approximately linearly with the number of cores in my system. The default settings is slower than four threads due to the code not being optimized by the JVM yet.

Default Settings
average time  174.04 (ms)

Threads are now off
average time  454.07 (ms)

Threads = 2
average time  233.76 (ms)

Threads = 3
average time  173.39 (ms)

Threads = 4
average time  129.55 (ms)

One word of warning. Concurrent algorithms in BoofCV are guaranteed to return equivalent but not identical results. For example, since by definition there's only one possible output for Gaussian blur concurrent and serial algorithms will be identical. On the other hand, a feature extractor will return the same features but in a different order that is non-deterministic.

Example Code:

Concepts:

  • Concurrency
  • Threads

Example Code

/**
 * Example for turning on and off concurrent algorithms, also known as multi-threaded algorithms.
 *
 * @author Peter Abeles
 */
public class ExampleThreads {
	public static void main( String[] args ) {
		// Create a 12 mega pixel image so that we easily see the affects of threading
		GrayU8 image = new GrayU8(4000, 3000);
		GrayU8 blurred = new GrayU8(4000, 3000);

		// fill the image with random data
		ImageMiscOps.fillUniform(image, new Random(), 0, 255);

		// By default threads are turned on and it uses the maximum number of threads
		System.out.println("Default Settings");
		blur(image, blurred);

		// Let's turn off threads and see how much slower it is. The number of physical cores
		// is the primary factor in determining the amount of speed up. Hyper threads only help a little bit
		System.out.println("\nThreads are now off");
		BoofConcurrency.USE_CONCURRENT = false;
		blur(image, blurred);

		// Let's turn threading back on. You should only really turn threads on and off when you first start
		// since the behavior later on isn't formally defined, but can be determined by browsing the source code
		BoofConcurrency.USE_CONCURRENT = true;
		// We will now change the number of threads to be 2,3, and 4. Look at how the speed changes
		for (int threadCount = 2; threadCount <= 4; threadCount++) {
			System.out.println("\nThreads = " + threadCount);
			BoofConcurrency.setMaxThreads(threadCount);
			blur(image, blurred);
		}
		// if the final average time you see is faster than the default that's likely caused by the hotspot compiler
		// warming up. The first iteration is always slower.
	}

	public static void blur( GrayU8 image, GrayU8 blurred ) {
		BlurFilter<GrayU8> filter = FactoryBlurFilter.gaussian(GrayU8.class, -1, 12);

		long time0 = System.nanoTime();
		for (int i = 0; i < 10; i++) {
			filter.process(image, blurred);
		}
		long time1 = System.nanoTime();

		System.out.printf("average time %7.2f (ms)\n", (time1 - time0)*1e-7);
	}
}