View Full Version : Internaly multi-threaded resampling functions
Pages :
1
2
3
4
5
[
6]
7
8
9
hello_hello
25th October 2024, 19:28
tormento,
for funzies I added an argument fullc (full chroma) to Resize8 if you want to play with it.
When fullc=true the output is always YUV444.
The chroma shift correction is applied accordingly, and I'm pretty sure it's the right amount, although I still don't know why ConvertToYUV444 appears to shift it more.
Link deleted. See post #253
tormento
25th October 2024, 23:11
tormento
Gonna test it ASAP.
hello_hello
26th October 2024, 15:31
After some more testing and comparing upscaling the chroma with Resize8 and AVSResize, I realized the Resize8 chroma shift correction for the test version I linked to is wrong. Only when upscaling the chroma though (when fullc=true and the source has subsampled chroma). Chroma shift correction for the standard resizing is fine. I'll upload a fixed version tonight or tomorrow.
tormento
28th October 2024, 11:46
I'll upload a fixed version tonight or tomorrow.
Just curious to know your findings. :p
Jamaika
6th November 2024, 06:56
I've made a plugin of the resampling functions, with internal multi-threading.
I can allready ear the "why" ?
The answer is "because"...:D
More seriously, i'll explain my point of view.
For multi-threading in image processing, if you have n cores, you have basicaly two ways :
Case 1 : You process n pictures in parallel.
Case 2 : You process n 1/nth part of the picture in parallel.
For me it's simple for gnu. Since the plugin has common ThreadPool::~ThreadPool() functions with avisynth then everything goes to the trash. I won't think about how to separate the thread functions since no definition has been added.
The same applies to HDRTools
Implemented new ideas about more flexible GaussResize : https://github.com/DTL2020/ResampleMT/releases/tag/pre-2.3.10
Added b, s params to GaussResizeMT
b - base value. Default 2.0, may be set to e-number 2.7 (2.71828...) for better precision of natural gaussian. Clamping range 1.5 to 3.5.
s - filter support. Default 4.0, if set to 0 - auto-support is enabled (it saves kernel down to 1% of its max value for support up to 150).
p-param limits relaxed from 0.1..100 to 0.01..100 to make larger blur if required.
Now it is possible to create large gauss blurs with auto-adjusting of support for resampler to keep all kernel working. Default support of 4.0 in old GaussResize limits working p-params to about 3..4. Now working is down to 0.01 (may require enough frame size for resampler to start with support about 100 and up to 150).
Pre-release for testing. Pull-request created.
Test script:
LoadPlugin("ResampleMT.dll")
BlankClip(100, 10, 10, color=$FFFFFF, pixel_type="YV12")
AddBorders(100,100,100,100,color=$000000)
GaussResizeMT(width, height, p=0.02, b=2.7, s=0, src_left=0.00001, src_top=0.00001)
LanczosResize(width*2, height*2, taps=10)
ConvertToRGB24(matrix="PC.601")
Better to make Animate with p from 0.02 to 20 to see the difference between auto-support (s=0) and default s=4 in old versions.
Example: old GaussResizeMT p=0.2, base 2.0, fixed support to 4.0 (zoom 400% in VirtualDub)
https://i.postimg.cc/tgxbFMj4/2025-03-09-232030.png
New GaussResizeMT p=0.2, base 2.0, auto-support (s=0)
https://i.postimg.cc/NG4c8XWm/2025-03-09-232215.png
jpsdr
25th March 2025, 14:41
The soon new posted version will not have the new resample engine.
I don't even know if i'll implement the new resample engine, because of alignement issues.
I've asked, but i'm almost sure AVS+ guarantee a higher minimum alignment than standard AVS. I don't see why pinterf in his new core code would bother checking alignment cases not hapening. Meaning that probably (i didn't check) this new code is not compatible for both standard AVS and AVS+, as it probably don't handle anymore alignment cases possible in standard AVS but not in AVS+. And as i want my plugin stay compatible with standard AVS and AVS+, it's unfortuntately highly possible that i'll don't upgrade and keep like it.
tormento
25th March 2025, 16:19
I don't even know if i'll implement the new resample engine, because of alignement issues.
That alignment issue is persecuting my thoughts since a long time.
What could be a general explanation / solution when you don't have to deal with half/double the original resolution?
@pinterf ? @anyone ?
jpsdr
25th March 2025, 18:11
The possible alignment issue has nothing to do with the resolutions...
Otherwise, new version, see first post.
StvG
26th March 2025, 00:46
The soon new posted version will not have the new resample engine.
I don't even know if i'll implement the new resample engine, because of alignement issues.
I've asked, but i'm almost sure AVS+ guarantee a higher minimum alignment than standard AVS. I don't see why pinterf in his new core code would bother checking alignment cases not hapening. Meaning that probably (i didn't check) this new code is not compatible for both standard AVS and AVS+, as it probably don't handle anymore alignment cases possible in standard AVS but not in AVS+. And as i want my plugin stay compatible with standard AVS and AVS+, it's unfortuntately highly possible that i'll don't upgrade and keep like it.
Can you write the specific reason why you want to keep the AVS compatibility? Can you write specific case/situation that AVS is doing better than AVS+? I cannot find situation where AVS+ fails but AVS is ok.
jpsdr
26th March 2025, 19:05
No specific, i just want to keep AVS compatibility for people who are still using it and using my plugins.
You're talking to someone who's still under Windows 7 (but with Openshell with Windows XP interface) because i hate the new interface, and even with Openshell Windows 10 interface is not back to my liking.
But unfortunately, i'll have no choice for the new gig i'm building... :(
jpsdr
2nd April 2025, 08:44
I will not implement the new optimized SSE/AVX2 code, but the rest: new coeff calcul and chroma, i will (or at least, i'll try).
I've pushed (but no build made) the first step of it. The new coeff calcul is implemented, but that's all, for now, the chroma is still the same as previous.
I've made only a few tests. If some people are also interested in testing and building, go ahead ! :D
Jamaika
3rd April 2025, 19:14
I've pushed (but no build made) the first step of it. The new coeff calcul is implemented, but that's all, for now, the chroma is still the same as previous.
I've made only a few tests. If some people are also interested in testing and building, go ahead ! :D
resample_functions.h:121:32: error: 'memset' was not declared in this scope
121 | if (bits_per_pixel<32) memset(pixel_coefficient,0,sizeof(short)*target_size*filter_size);
| ^~~~~~
I'm curious. Will all aligned functions be cut out in the end like in avisynth?
switch(data->f_process)
{
//case 1 : ptrClass->ResamplerLumaAlignedMT(MT_DataGF);
//break;
case 2 : ptrClass->ResamplerLumaUnalignedMT(MT_DataGF);
break;
//case 3 : ptrClass->ResamplerUChromaAlignedMT(MT_DataGF);
//break;
case 4 : ptrClass->ResamplerUChromaUnalignedMT(MT_DataGF);
break;
//case 5 : ptrClass->ResamplerVChromaAlignedMT(MT_DataGF);
//break;
case 6 : ptrClass->ResamplerVChromaUnalignedMT(MT_DataGF);
break;
//case 7 : ptrClass->ResamplerLumaAlignedMT2(MT_DataGF);
//break;
case 8 : ptrClass->ResamplerLumaUnalignedMT2(MT_DataGF);
break;
//case 9 : ptrClass->ResamplerLumaAlignedMT3(MT_DataGF);
//break;
case 10 : ptrClass->ResamplerLumaUnalignedMT3(MT_DataGF);
break;
//case 11 : ptrClass->ResamplerLumaAlignedMT4(MT_DataGF);
//break;
case 12 : ptrClass->ResamplerLumaUnalignedMT4(MT_DataGF);
break;
default : ;
}
I am interested in the output parameter color range tv {range=2}. When is it active?
jpsdr
4th April 2025, 18:10
I have no issue building with either Visual Studio 2010 or 2019, the memset issue is odd...
As i said, there will be no change in my code of the core resample function, my code is:
void FilteredResizeV::StaticThreadpoolV(void *ptr)
{
Public_MT_Data_Thread *data=(Public_MT_Data_Thread *)ptr;
FilteredResizeV *ptrClass=(FilteredResizeV *)data->pClass;
MT_Data_Info_ResampleMT *MT_DataGF=((MT_Data_Info_ResampleMT *)data->pData)+data->thread_Id;
switch(data->f_process)
{
case 1 : ptrClass->ResamplerLumaAlignedMT(MT_DataGF);
break;
case 2 : ptrClass->ResamplerLumaUnalignedMT(MT_DataGF);
break;
case 3 : ptrClass->ResamplerUChromaAlignedMT(MT_DataGF);
break;
case 4 : ptrClass->ResamplerUChromaUnalignedMT(MT_DataGF);
break;
case 5 : ptrClass->ResamplerVChromaAlignedMT(MT_DataGF);
break;
case 6 : ptrClass->ResamplerVChromaUnalignedMT(MT_DataGF);
break;
case 7 : ptrClass->ResamplerLumaAlignedMT2(MT_DataGF);
break;
case 8 : ptrClass->ResamplerLumaUnalignedMT2(MT_DataGF);
break;
case 9 : ptrClass->ResamplerLumaAlignedMT3(MT_DataGF);
break;
case 10 : ptrClass->ResamplerLumaUnalignedMT3(MT_DataGF);
break;
case 11 : ptrClass->ResamplerLumaAlignedMT4(MT_DataGF);
break;
case 12 : ptrClass->ResamplerLumaUnalignedMT4(MT_DataGF);
break;
default : ;
}
}
and will not change.
If no range is specified (default mode auto), tv is active for all YUV formats.
jpsdr
4th April 2025, 21:16
Still no build for now, but i've pushed the final step of resampler update, added keep_center and placement parameters.
Very first quick test, seems to work.
jpsdr
6th April 2025, 11:35
... It seems that i have an issue with AVX2 & AVS+, but not with AVX2 and AVS...
Argh... ! :(
As my standard PC with Visual Studio hasn't AVX2, and my default is with AVS, didn't see it in very quick test...
Up to Visual Studio 2017 we have good (full) integration of SDE from intel. So if you use VS2015 (?) or VS2017 (and may be some old ?) you can download and install intel SDE and have full AVX2 (and AVX512) simulation at about any intel (?) CPU. Simply select SDE debugger in the IDE.
jpsdr
7th April 2025, 21:59
Pushed a new version, i made more tests, i think everything is good now.
Builds comming soon.
jpsdr
9th April 2025, 18:09
New version, see first post.
DTL
10th April 2025, 14:44
With ver 2.5.1 looks edges processing is good enough. Very small difference with internal AVS+ resize:
Loadplugin("ResampleMT.dll")
Function Diff(clip src1, clip src2)
{
return Subtract(src1.ConvertBits(8),src2.ConvertBits(8)).Levels(120, 1, 255-120, 0, 255, coring=false)
}
BlankClip(100, 200, 100, color=$7F7F7F, pixel_type="YV12")
AddBorders(2, 2, 2, 2, r=2, param1=8)
pad=50
std=LanczosResize(width*2, height*2, taps=16).Subtitle("AVS+ Std 2xLanczosResize taps=16", align=5)
mt=LanczosResizeMT(width*2, height*2, taps=16).Subtitle("ResampleMT 2xLanczosResize taps=16", align=5)
d1 = Diff(mt,std)
d2 = Diff(mt,std)
StackHorizontal(StackVertical(std, mt), Stackvertical(d1, d2))
https://i.postimg.cc/wyRFphpT/image-2025-04-10-164423959.png (https://postimg.cc/wyRFphpT)
jpsdr
10th April 2025, 18:07
... In theory, there shouldn't have a difference...
I'll make some quick test, but for now, i will not spend more time on this.
DTL
10th April 2025, 21:45
SIMD resampling functions are still different. I use E7500 CPU pre-AVX. So it run some SSE SIMD for computing.
No difference only with SetMaxCPU("none").
pinterf
14th April 2025, 16:09
A small note on why the changes shouldn't be adopted immediately: The resampler code (SSEx, AVX2) is being modified slightly. The 8-bit and 10-16 bit cases differed only in a few lines, so their code was mostly duplicated. I've unified them and put them into templates. Additionally, the plain C code is being reorganized to help compiler auto-vectorization when built on non-Intel systems. Neither of these changes has been committed to the live system yet, as cleanup is needed on my side. Since there is no release date push on me, it may be finished in some weeks.
jpsdr
14th April 2025, 16:45
Thanks for this information.
Anyway, i've just updated the chroma position and coeff/border calcul.
I didn't update the resampler code (SSEx, AVX2), and honestly don't intend to, it will be too much work. There is allready an optimized code (which is good enough for me and compatible AVS & AVS+), and for me, i've implented what realy matters : chroma & coeff.
DTL
14th April 2025, 18:58
A small note on why the changes shouldn't be adopted immediately: The resampler code (SSEx, AVX2) is being modified slightly.
I see you use currently dual 256bit SIMD dataword load+processing+store for better performance at
https://github.com/AviSynth/AviSynthPlus/blob/718a1380c0f416cb014a1575627b3f1d2601e848/avs_core/filters/intel/resample_avx2.cpp#L84
But have you test more 'workunit size' for AVX2 (also at AVX512 chips) ? Like 4 of 256bit SIMD datawords in 'parallel' ? It is expected if some chips have more dispatch ports or ports with more width (like 512bit) it possibly may dispatch more operations per cycle. Or it is subject to test in future ? Also are AVX512 version expected ?
For some of used instructions _mm256_add_epi32 the Throughput is 3 results per cycle even at very old already chips:
https://i.postimg.cc/8k7bhdSS/2025-04-14-222721.png
The Latency of _mm256_madd_epi16
https://i.postimg.cc/SNWCrD1w/2025-04-14-223224.png
is 5 cycles so it output 2 results after 5 cycles delay but can output 2 results per cylcle each next cycle is sources were ready to compute. So to hide startup latency it may be also better to provide > 2 source datasets to compute.
We also have some example of larger 'workunit size' for AVX2 processing in vsTTempSmooth plugin - it loads and process 4x256 bit data for 1 loop spin: https://github.com/Asd-g/AviSynth-vsTTempSmooth/blob/97fda577d1ef7dc4aacb532ccbc51bbcdf5335d7/src/vsTTempSmooth_AVX2.cpp#L71 As I remember this make some performance boost over 1 and 2 256bit datasets.
DTL
30th April 2025, 04:59
I understand one more cache-unfriendly point of current dual-1D resampling engine for Resize() core filter and it looks like same for MT resize (it is currently filter-sequence):
For multi-plane formats it first processes all planes in a sequence for H or V resize and next processes all planes for the second dimension.
This cause trashing of the old 1D-processed by 1 of 2 required resizes planes from the cache and can decrease performance if all 3..4 planes of multi-planes formats can not be fitted in CPU cache.
So one more cache-friendly logic optimization is changing a sequence of frames resample to a sequence of planes of frame resample.
Though as current tests for AVS+ core resamplers shows they are mostly compute-bounded and not memory-bounded but after next stage of compute engines optimization the memory-performance bounding condition may raise again.
jpsdr
19th June 2025, 14:44
Checked my code, and noticed something i forgot : i use AVX2 functions only if i am with AVS+, meaning the non aligned issue of AVS... is just not possible (and that's probably for avoiding it that i made it this way). So, maybe i'll check if i can also update to the new AVX2 code.
jpsdr
22nd June 2025, 13:15
Hello.
New version, see first post.
jpsdr
23rd June 2025, 12:47
No promises, but i'll try to see what i can get from new resample_sse.c without breaking avs compatibility.
(Worst case, i still can rename sse avsp specific functions, and make avsp specific code path...).
jpsdr
26th June 2025, 19:36
No build yet, but i've pushed the use of the new resample_sse code.
Using DTL script with SetCPUMax added on the top of it, i've been able to check i think the big majority of path code. Total flat difference result, except... for the 8 bit pure "C" vertical code.
I've checked, checked, re-checked and re-checked, and i don't understand why there is a difference.
For the "C" code, i didn't use the "infernal" vectorised optimised "C", but the standard reference code left, which had just a little optimisation. So, i don't know why, but i don't have the exact same result with it than the "infernal" version for vertical 8 bits.
jpsdr
29th June 2025, 09:58
New version, see first post.
jpsdr
20th July 2025, 10:21
New version, see first post, but small change.
Can you add some way of planes processing control ? Most of the reasons and possible example how to implement without adding more params described in https://github.com/AviSynth/AviSynthPlus/issues/447 .
As I see users of executables in scripts select additional plugins for performance and script simplicity. It is more simple in script to set planes to process only in comparison with plane extracting (also may cause performance penalty and data copy ?).
This cause additional scripts dependencies and may suffer from additional plugins issues.
If GaussResize(MT) can do very frequently required simple gauss LPF/blur - users can use it instead of old plugins. But in real scripting they use simple additional control features like planes processing control. It was not natural for resizers and was not implemented in old versions of resizers.
jpsdr
1st August 2025, 17:50
I'll see... It's not a "yes", but it's not a "no" also.
Edit:
I didn't realised, but can you explain to me what "copy" means with a resampler...????
DTL
1st August 2025, 20:00
Copy mode only valid with no-resize processing (convolution with resize kernel only). Like in the usage example of QTGMCp script -
https://github.com/Dogway/Avisynth-Scripts/blob/c6a837107afbf2aeffecea182d021862e9c2fc36/MIX%20mods/QTGMC%2B.avsi#L678
vsTCanny(1.4,mode=-1,u=1,v=1) - user need to gauss-blur only Y-plane and skip processing of the UV planes completely (return allocated RAM from AVS core for YUV input format - fastest mode).
With updated version of resize it is expected like
GaussResize(MT)(width=inp_width, height=inp_height, s=0, p=some_val, force=3+planes_processing_control_flags)
Possible other use case - user need to perform some convolution with any supported kernel only for Y or UV planes and need other planes unchanged (copy mode). In scripting form it is a sequence like
1. Extract plane
2. Process required plane
3. Combine planes
But this is longer in scripting and also can cause performance degradation on more plane copies.
You can throw error if copy mode activated/requested in plane resize mode.
Third mode 'skip plane writing' may be valid with resize processing too.
Also some math optional view: copy is no-resize convolution with 1-kernel (delta-function normalized ?) (where f(x)=1 at x=0 and f(x)=0 at x!=0). Also no-resize PointResize action.
If the feature request will be implemented in AVS+ core - it still can not be complete replacement of your plugin becuase AVS+ core uses inter-frame MT and your plugin uses intra-frame MT. So depend on the use case we need either internal AVS+ core processing or your plugin (user need to test both ways and select the fastest).
The output expected to be equal but performance depend on current CPU and script environment.
jpsdr
1st August 2025, 20:31
I still don't understand...
You mean you call the resizer without shift, crop and without changing the size ??? What the point ? It will just do nothing, no ??? (I must confess i don't know, maybe i'll check in the code if i take a look at this feature).
Well... Whatever the resizer is doing, copy could be allowed only if :
All shift=0, all crop=0, and outputsize=inputsize, otherwise, only processing or output garbage would be allowed.
And using force is interesting, as there is no need to add another parameter...
DTL
1st August 2025, 21:13
"It will just do nothing, no ???"
With force=3 it will perform no-resize (but resampling as changing samples values) convolution with resize kernel. Square frequency response kernels with cut-off of Fs/2 will really 'do nothing' (for perfectly conditioned for band-limited channel source) or expose some Gibbs ringing. It also may be some use case for 'anti-ringing' processing when users get ringed version after convolution with such kernel and attempt to subtract with original to get ringing only difference. Examples of such kernels are Sinc/Lanczos/SincLin2. But if kernel make some amplification of suppression of frequencies in range of 0 to Fs/2 - it will cause other effects on image.
See example at https://forum.doom9.org/showthread.php?p=2016041#post2016041
With resize processing it change both samples count and samples values (most classic example of resampling). Because kernels for downsampling are typically have some low-pass filter action it will cause some low-pass plane buffer processing. These are kernels of GaussResize, SinPowResize, UserDefined2Resize at least. Most frequently used kernel for low-pass filtering (blurring) is Gauss.
Yes - I forgot about shift and crop. If shift (at sub-sample distance) is requested - the copy may be allowed (it will cause shift only requested planes and copy of marked to copy). It is also some known use case when user need some sub-sample luma/chroma alignment changes (change chroma placement or luma/chroma relative placement) and need to shift-process only Y or UV planes. Typical shift kernels are sinc-based like SincLin2Resize (or any other weighed sinc like Lanczos).
I do not use crop typically and can not quickly suggest if copy mode can be used with large (>1.0 sample size) crop requested.
"Whatever the resizer is doing, copy could be allowed only if :
All shift=0, all crop=0, and outputsize=inputsize, "
Also if shift (src_left and/or src_top) is in range 0.0 to 1.0f. If user need to do some sub-sample alignment of planes without changing planes size in samples. Most common use case is 'chroma placement adjustment'.
"using force is interesting, as there is no need to add another parameter..."
Yes - it is close to the 'force' parameter logic. It now control 'force (plane) process or not' and can control 'how to process'. And because it is integer param of at least 32bit value we can use some bithacks to encode some additional planes processing control as bitfields above currently used 2LSBs for 0,1,2,3 contol values encoding. We need to add control up to 4 possible planes (up to YUVA/RGBA) formats.
jpsdr
2nd August 2025, 10:40
Honestly, if i try to implement this, i will not try to figure out what crop/shift/etc... combination would allow copy, i'll make my life easy with the condition i've stated.
DTL
2nd August 2025, 21:12
It is enough to implement only working control of plane skip and plane copy and make note into documentation about being valid only in limited use cases.
DTL
3rd August 2025, 10:06
I am going thru a very strange bug with SinPowResizeMT and lineart.
It produces really jagged lines with halo "sparks" (please, zoom the image).
Any idea?
I found some issue with small resampling ratios (and odd-numbered output size) in current AVS+ resampler causing significant kernels distortion - https://github.com/AviSynth/AviSynthPlus/issues/431#issuecomment-3148256363
It may cause such resize distortions too. Will try to see what may be wrong or may be pinterf find this faster.
jpsdr
3rd August 2025, 11:04
@DTL
Hi.
I want to make some test, can you tell me what resizer and parameters to use to have a filter size of at least 100 ?
DTL
3rd August 2025, 14:42
As we see in current AVS+ sources - https://github.com/AviSynth/AviSynthPlus/issues/431#issuecomment-3148256363
Current filter size computing
AviSynthPlus/avs_core/filters/resample_functions.cpp
Line 339 in 7ae5d48
int fir_filter_size = std::max(int(std::ceil(filter_support * 2)), 1);
Where filter_support is support member of filter kernel function. It is equal to taps for sinc-based resizers. So to have filter size (sent to resampler for convolution) at least 100 you can call any sinc-based resizer with taps > 50. Lets test SincResize(taps=60) . Width and height may be about 200x200 or more.
As I remember taps param is internally limited to some low values for different sinc-based resamplers. And it is limited without throwing an error and user do not know about limitation. But for SincResize upper limit was relaxed to 150 (in your sources too https://github.com/jpsdr/ResampleMT/blob/e041491f9ecc10a2741dc03f01e4938066a396d8/ResampleMT/resample_functions.cpp#L296 ) to use it with low edge of kernel compute issue. I think filter size of 100 is about never used in real use cases.
Also in your sources GaussResize max support is 150 https://github.com/jpsdr/ResampleMT/blob/e041491f9ecc10a2741dc03f01e4938066a396d8/ResampleMT/resample_functions.cpp#L260
So you can also test GaussResize(s=60, p=0.01)
jpsdr
3rd August 2025, 16:56
Ouch...:eek:
I made some bench test and i must confess i didn't expect a so bad result... :(
Either i totaly misunderstood the horizontal intrinsic of pinterf (wich is possible because i was lost in the call of call of call... of functions) and so my asm implement is totaly wrong (even if the output result match perfectly), either intrinsic produce results a looooot beter than i tought, and i was totaly wrong (which is also possible) and my asm implement is what pinterf has done.
My asm is 2 time slower thant intrinsic... :(
I should have done speed test before making a release... But again, i must confess i didn't expect this result.
Life is full of surprises (good and bad).
DTL
3rd August 2025, 17:31
2 times slower is not very bad. In 3.7.4 H-resize is about 4+ times slower in comparison with V-resize and different variations of the design idea of H-resize may give 2..3+ times faster solution. But some implementations are limited with max supported filter size or resize ratio.
Universal solution for H-resize supporting any filter size and any input source offset for the currently processed output samples set in a SIMD pass (resize ratio) expected to be not of best performance. And partially limited solutions may be significantly faster.
Also intrinsic-based solution allow more easy increasing 'working unit' size for single SIMD pass without thinking about registers usage and also compiler can do some optimizations too. Also no need to make separate x86 and x64 .asm implementations manually.
If you look into some design tests of different H-resampler implementations at https://github.com/AviSynth/AviSynthPlus/pull/440 its performance may be different in about 5+ times depending on the design idea used and compiler and SIMD family. Also significantly depend on filter size supported by implementation.
Currently fastest in my test is resize ratios about 0.5 to infinity and filter size up to 8 using dual-512 bit source permutex for V-fma with AVX512. But it do not support downsize ratios below about 0.5 and do not support (directly) filter size above about 8..16. The design idea of this implementation is load part of source row into 2 512 bit registers and convert resampling program into permute program for AVX512 engine to gather source samples in required V-order for standard V-fma using AVX512 dual-512 input permutex instructions. Where data permutex performed only inside register file. Any gathering from other memory (based from offsets from resampling program) cause significant performance loss.
jpsdr
3rd August 2025, 17:46
I take a look, and indeed i made for horizontal something totaly different, which i think is probably a lot less memory cache efficient, which could explain the speed difference.
I think for vertical i made the same thing than pinterf's, code was a lot easier to read.
I'll try, but latter for now, to make an horizontal following what pinterf has done.
DTL
3rd August 2025, 19:19
Verticals are very SIMD friendly (though not very SDRAM friendly) and simple in design. The only possible performance optimization is adjusting 'workunit size' to fit current capacity of SIMD register file with better to use H-expansion. In 3.7.5 someone make V-expansion (pairs of rows processing) and it may be less cache/memory friendly because create more read streams with large stride. Better to create less number of read streams of longer size - see
https://github.com/DTL2020/AviSynthPlus/blob/034a47e2c91ad9d84ad24492d37a18f99b58d996/avs_core/filters/intel/resample_avx512.cpp#L1723 - first is 128 samples wide and last
https://github.com/DTL2020/AviSynthPlus/blob/034a47e2c91ad9d84ad24492d37a18f99b58d996/avs_core/filters/intel/resample_avx512.cpp#L1806 is 64 samples (bytes) wide. AVS+ have row size of mod 64bytes and it expected to be safe for read/write to the end of row.
This cause separation of row processing to several stages. First size is mod of largest fit in register file and end of row with lower lengths.
rgr
4th August 2025, 11:29
What happens to the 0-15 and 235/240-255 ranges in YUV limited mode? Are they clipped?
tormento
4th August 2025, 13:34
I take a look, and indeed i made for horizontal something totaly different
I am currently using AVX MSVC x64 version of your plugins.
Tried 3.8.0 and had to revert to 3.7.0.
Can't understand what's wrong. StaxRip crashes, VirtualDub shows black screen and AVSPmod exits with no warning or error.
My cpu is a i7-2600k with AVX support only.
My script:
SetMemoryMax()
SetFilterMTMode("DEFAULT_MT_MODE", 2)
LoadPlugin("D:\Eseguibili\Media\DGDecNV\DGDecodeNV.dll")
Import("D:\Eseguibili\Media\StaxRip\Apps\Plugins\AVS\DehaloAlpha\Dehalo_alpha.avsi")
Import("D:\Eseguibili\Media\StaxRip\Apps\Plugins\AVS\Dither\mt_xxpand_multi.avsi")
Import("D:\Eseguibili\Media\StaxRip\Apps\Plugins\AVS\FineDehalo\FineDehalo.avsi")
DGSource("M:\In\My hero academia S3 ~720p bil Dynit\21-4.dgi")
z_ConvertFormat(resample_filter="Bicubic", pixel_type="yuv420p16")
DeBilinearResizeMT(1280, 720, threads=1, prefetch=2, accuracy=2)
z_ConvertFormat(resample_filter="Spline64", pixel_type="yuv444ps")
BM3D_CUDA(sigma=12, radius=4, chroma=true, block_step=6, bm_range=12, ps_range=6)
BM3D_VAggregate(radius=4)
z_ConvertFormat(resample_filter="spline64",dither_type="error_diffusion",pixel_type="YUV420P16")
FineDehalo(rx=2, ry=2, thmi=80, thma=128, thlimi=50, thlima=100, darkstr=0.3, brightstr=1.0, showmask=0, contra=0.0, excl=true)
libplacebo_Deband(radius=14, iterations=6, temporal=false, planes=[3,3,3])
fmtc_bitdepth (bits=10,dmode=8)
Prefetch(2,6)
jpsdr
4th August 2025, 18:16
Ah...
My issue is that i have an SSE4.1, an AVX2 and AVX512 CPU, but not an AVX only. So, i can with AVX2 test the AVX2 code to be sure i didn't left any "more than AVX2" code, but unfortunately i can't do that for AVX, as i don't have an AVX only CPU...
I can test the AVX path code with SetCPUMax, but not the fact if i forgot some AVX2 code.
My guess is that i left some AVX2 code in the AVX code... :(
In the first time, i can provide you the following steps :
- Resample changing only horizontal or vertical size, this will tell if crash occurs in vertical or horizontal resizer.
- Then test the following video cases : 8bits, 10bits, 16bits, 32bits.
- Does the crash occurs also with the x86 version ?
If you don't have time or don't want to do it, absolutely no hard feelings, do the tests only if you want.
tormento
4th August 2025, 18:55
In the first time, i can provide you the following steps:
- Resample changing only horizontal or vertical size, this will tell if crash occurs in vertical or horizontal resizer.
- Then test the following video cases : 8bits, 10bits, 16bits, 32bits.
- Does the crash occurs also with the x86 version ?
If you don't have time or don't want to do it, absolutely no hard feelings, do the tests only if you want.
It seems that, in some cases, it affected 3.7.0 too but I never tried that specific parameter combination.
Used VirtualDub as AVSPmod crashes when not working, instead of giving black screen.
3.7.0
8,10,16,32 bit, H only resize → working
8 bit, V only resize → black screen
10,16,32 bit, V only resize → working
3.8.0
8,10,16,32 bit, H only resize → working
8 bit, V only resize → working
10,16,32 bit, V only resize → black screen
I don't use x86 at all.
vBulletin® v3.8.11, Copyright ©2000-2026, vBulletin Solutions Inc.