Repository navigation
BoxBlur(1) on Image<L8>: is the generic Vector4 path expected? (ImageSharp 3.1.12) #3212
|
I'm working on a university image-convolution project. My own 3×3 box blur was faster than ImageSharp's Controlled comparisonThe two runs below use the same
The images are 3840×2160. Measurements are Release/.NET 9, one warm-up and five full-folder runs per variant, in shuffled order; these are medians of elapsed time measured by L8-only control filterusing System;
using System.Threading.Tasks;
using SixLabors.ImageSharp;
using SixLabors.ImageSharp.Advanced;
using SixLabors.ImageSharp.PixelFormats;
static void GrayBoxBlur(Image<L8> image, ParallelOptions options)
{
int width = image.Width, height = image.Height;
using var middle = new Image<L8>(width, height);
Parallel.For(0, height, options, y =>
{
Span<L8> input = image.DangerousGetPixelRowMemory(y).Span;
Span<L8> output = middle.DangerousGetPixelRowMemory(y).Span;
for (int x = 0; x < width; x++)
{
int sum = input[Math.Max(0, x - 1)].PackedValue
+ input[x].PackedValue
+ input[Math.Min(width - 1, x + 1)].PackedValue;
output[x] = new L8((byte)((sum + 1) / 3));
}
});
Parallel.For(0, height, options, y =>
{
Span<L8> above = middle.DangerousGetPixelRowMemory(Math.Max(0, y - 1)).Span;
Span<L8> current = middle.DangerousGetPixelRowMemory(y).Span;
Span<L8> below = middle.DangerousGetPixelRowMemory(Math.Min(height - 1, y + 1)).Span;
Span<L8> output = image.DangerousGetPixelRowMemory(y).Span;
for (int x = 0; x < width; x++)
{
int sum = above[x].PackedValue + current[x].PackedValue + below[x].PackedValue;
output[x] = new L8((byte)((sum + 1) / 3));
}
});
}For context, my own row-parallel CPU implementation completed the same folder in 4.201 s, but that row uses a different load/save path, so the 8.417 vs 2.872 s pair above is the controlled comparison. The process's total CPU time (summed across threads, including I/O) was 92.344 s with BoxBlur and 28.047 s with the L8-only control. In a separate Visual Studio CPU Usage sample of repeated BoxBlur calls on a preloaded Environment and question
Is the general |
Replies: 1 comment
|
Yes, the Your control is specialized for There is no configuration switch that selects an L8-only box blur. Your conversion profile is useful evidence of an optimization opportunity, but the use of |
Yes, the
Vector4path is expected. ImageSharp processesTPixelthrough a common floating-point representation so the same convolution implementation works across pixel formats and retains precision during the calculations. It also handles alpha correctly for formats that have it.Your control is specialized for
L8, a fixed three-pixel kernel, and opaque grayscale data. It can avoid the pixel conversions and general processing work, so it is reasonable for that narrower implementation to be faster. Matching output for these inputs does not remove the need for the generic path.There is no configuration switch that selects an L8-only box blur. Your conversion profile is useful evidence of a…