Log in

View Full Version : AviSynth+ thread Vol.2


Pages : 1 2 3 4 5 6 7 8 9 [10] 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75

vcmohan
11th June 2020, 07:08
https://github.com/AviSynth/AviSynthPlus/blob/9a813c1bdfec9d35252ca489e01ea059a6323783/avs_core/core/BufferPool.cpp#L105
Looks like BufferPool::Allocate does some job to don't allocate new buffers if possible, so it should be faster if you use allocation per getframe (if buffer allocation is pooled, it will not be freed but marked as reusable, see BufferPool::Free). i didn't dig too deep, but assume it's freed at destruction or on cache adjustment.

It looks like it should work. But do I need to include BufferPool.cpp in my build. Or since it is listed under core of avs+, is there a way of calling this function? Does it work with 3.5 version?

pinterf
11th June 2020, 07:52
It looks like it should work. But do I need to include BufferPool.cpp in my build. Or since it is listed under core of avs+, is there a way of calling this function? Does it work with 3.5 version?

No. BufferPool.cpp was just linked as an example where you can see how avs+ implements it and that behind env->Alloc there is really a pool.

If you have V8 (avs+ 3.6), use env->Allocate and env->Free.
If you don't have, use aligned alloc/free or _mm_alloc/free, or alloca. Since memory pools are good at frequent alloc/free, probably they are recommended only for in-GetFrame use.

The whole (thread/memory) "pool" theory is based on that creation and free of such resources can take time. But if they are allocated already and are used on-demand and they are only going idle when not used, this is more optimal and takes less time.

Myrsloik once wrote that small allocations provided by usual tools are fast enough but larger ones (like frames) are much slower to allocate.

You can benchmark your case if env->Alloc gave you any speed or memory use benefit vs. usual C++ provided allocation methods. I'd say it's fine tuning.

pinterf
11th June 2020, 08:01
If _mm_alloc is available then why is env->Allocate introduced? Or as I think _mm_alloc is a system call. If so if done for each frame, it will slow down and MT may be a waste. Am I correct?
env->Allocate is an Avisynth+ interface method.
_mm_alloc is a SIMD-like intrinsic which is provided by your C++.
Other aligned alloc and free methods are provided by your C++ as well.
I don't know what your filters do but run benchmarks how your filter's real workload compares to the allocation time itself.

MeteorRain
11th June 2020, 11:35
Yet it's slower on complex scripts + encoding (judging from eedi3/nnedi3), so I think internal mt should be off by default. The only useful case with internal threading is when we preview stuff in avspmod or another host, since usually there is no need in computation of 24 frames (my case) when tweaking filter.

I would argue that internal MT is slow because it's not used in the most efficient way. The best way to do it would be having a globally available thread pool running somewhere, then having internal MT from multiple filters sharing the same pool, and then having a light parallel frame prefetching. (Like prefetch(4) on a 32 cores.)

Yes, a thread pool just like the multiple attempts that our friends tried, but in a more elegant way. Maybe after we have C++23 executor extension we can somehow make it easier and better.

vcmohan
11th June 2020, 12:40
env->Allocate is an Avisynth+ interface method.
_mm_alloc is a SIMD-like intrinsic which is provided by your C++.
Other aligned alloc and free methods are provided by your C++ as well.
Thanks. As I am unable to get buffers from the pool in case of pre_version 8, I am weighing the option of MT_SERIALIZING for that situation. Between MT_NICE_FILTER and MT_MULTI_INSTANCE what is the difference? Does SetCacheHints get called invariably or only in case previous filters are thread safe?
I am asking because I want to set some flags if multi threaded.

pinterf
11th June 2020, 13:03
SetCacheHints (note: name is misleading, avisynth extended an existing mechanism to ask info from filters) is always asked after filter constructor so your filter can report its behaviour depending on your actual filter parameters.
Specify "nice" when your filter can be fully reentrant, practically stateless, filter does not write class variables (there are specialized cases, guarded by mutex, but I'm speaking in general)
I still cannot see your use case, the reason why you want your filter make MT_SERIALIZED when you cannot use env->Allocate? Is it really that much time or memory penalty?

vcmohan
11th June 2020, 13:38
Then what is MT_MULTI_INSTANCE ?
In case in script the function is set as MT_SERIALIZED, even though the function internally is declared as NICE, Or one of the previous filters is MT_SERIALIZED does it still run SetCacheHints on subsequent filters? It was noted that this will be propogated downward and not upward.

pinterf
11th June 2020, 14:05
http://avisynth.nl/index.php/AviSynth%2B#Choosing_the_correct_MT_mode
Filters do not affect each other's mt modes.
But when a slowish filter is MT_SERIALIZED it will create a bottleneck. Imagine when you drive on an eight-lane highway but there is a single-lane exit

vcmohan
11th June 2020, 14:35
http://avisynth.nl/index.php/AviSynth%2B#Choosing_the_correct_MT_mode
Filters do not affect each other's mt modes.
But when a slowish filter is MT_SERIALIZED it will create a bottleneck. Imagine when you drive on an eight-lane highway but there is a single-lane exit

Thanks,. It means what we declare in the script file does not matter? And what was meant by the comment in header file 'it is popogated down but not upwards'?

I have another question. libfftwf3 dll is thread safe. However it has to be informed number of threads that will be active. How can I get this info from avisynth+ ?

pinterf
11th June 2020, 15:33
Thanks,. It means what we declare in the script file does not matter? And what was meant by the comment in header file 'it is popogated down but not upwards'?

You mean by SetFilterMTMode?
Default is MT_MULTI_INSTANCE as it is the most likely one that works by default for filters. When filters are specifying their MT modes with SetCacheHint it will be used then instead. When a filter is specifying its MT mode _and_ there is a SetFilterMTmode found, it will only be used when a last "force" bool parameter is set to true.


I have another question. libfftwf3 dll is thread safe.

Note: but plan creation is _not_ threadsafe, you have to use mutex or other guards for that.
Sample:
https://github.com/pinterf/mvtools/blob/mvtools-pfmod/Sources/DCTFFTW.cpp#L101


However it has to be informed number of threads that will be active. How can I get this info from avisynth+ ?
You cannot query that.
I'm not familiar with that, you have to specify the number of thread each call will spawn for each call fft3w? MeteorRain is surely an expert on this.

vcmohan
12th June 2020, 07:40
Thanks. As I understand that eventhough I might have in the script
SetFilterMTMode("F1Quiver", MT_Multi_instance)
if inside F1Quiver I have returned for SetCacheHints(....) override . MT_NICE_FILTER, the script will run as if it is a nice filter.

In fft, prior to creating plans I need to declare that internally all actions to run thread safe need to be taken, but in that number of threads are to be specified. The code I use is
SYSTEM_INFO sysinfo;
GetSystemInfo(&sysinfo);

numCPU = sysinfo.dwNumberOfProcessors;

fftwf_init_threads();

fftwf_plan_with_nthreads(numCPU * t);

This I do in the constructor and so far have not come across any problem. Usually I keep t equal to. 2 is arbitrary.
As I declared the filter as NICE, I presume it will run in 8 threads on my system with 4 processors

MeteorRain
12th June 2020, 07:49
fftw3 is thread safe but I think each execution is internal-threaded. AviSynth+ is external multi threaded.

In other words, with prefetch(4), your downstream is calling 4 GetFrame() from you at the same time in 4 different threads, and for each call, you connect to fftw3 and do some transform.
Now if you set threads=2 for fftw plans, then you will end up with 4×2=8 concurrent threads, using up to 8 CPU "core"s.

There's no reliable way to find out how many threads your downstream is calling you. You can have some way to figure out but (hint: very ugly) (https://github.com/HomeOfAviSynthPlusEvolution/neo_FFT3D/blob/master/src/fft3d_engine.h#L471).

Groucho2004
12th June 2020, 08:36
The code I use is
SYSTEM_INFO sysinfo;
GetSystemInfo(&sysinfo);

numCPU = sysinfo.dwNumberOfProcessors;

fftwf_init_threads();

fftwf_plan_with_nthreads(numCPU * t);

This I do in the constructor and so far have not come across any problem. Usually I keep t equal to. 2 is arbitrary.
As I declared the filter as NICE, I presume it will run in 8 threads on my system with 4 processorsWhat purpose does the variable "t" have? Can you elaborate?

pinterf
12th June 2020, 08:56
As there is no negative feedback on 3.6.1 test8 build, I finalize the changes.

Selur
12th June 2020, 10:32
'PlanarTools.dll' (https://github.com/chikuzen/PlanarTools/releases/download/0.3.0/PlanarTools-0.3.0.zip)
give "cannot be used as a plugin for AviSynth" with 3.6.1 test8 build

pinterf
12th June 2020, 10:50
'PlanarTools.dll' (https://github.com/chikuzen/PlanarTools/releases/download/0.3.0/PlanarTools-0.3.0.zip)
give "cannot be used as a plugin for AviSynth" with 3.6.1 test8 build
Wasn't it in the plugin set which asd-g rebuild from chikuzen's repository?
Which other plugin or script requires that? I saw that you've got an interlaced YUY2 but what if you convert it to interlaced YV16? Or we face another yv12-yuy2-only plugin?

Selur
12th June 2020, 11:18
Wasn't it in the plugin set which asd-g rebuild from chikuzen's repository?
Nope, there's no PlanarTools repostitory from https://github.com/Asd-g

I saw that you've got an interlaced YUY2 but what if you convert it to interlaced YV16? Or we face another yv12-yuy2-only plugin?
PlanarTools (http://avisynth.nl/index.php/PlanarTools) supports "RGB24, RGB32, YUY2, Y8, YV12, YV16, YV24", the problem is that the LoadPlugins fails not that PlanarTools itself crashes upon usage.

Which other plugin or script requires that?
It's used in AnimeIVTC and by proxy in QTGMC (since that nowadays uses parts of AnimeIVTC).
It's not 'required', as the script can be used without it, but it gives a speed boost for YUY2 processing.
-> I could live without it (authors of AnimeIVTC should adjust its script accordingly, but thats another issue), just wanted to let you know that it's not working, since you posted 'As there is no negative feedback on 3.6.1 test8 build'. :)

Cu Selur

pinterf
12th June 2020, 11:59
What speed boost? Planartools converts YUY2 to Planar-in-fake-YUY2 but in an unofficial (but widespread at those old times) way. Because YV16 (planar 4:2:2) was introduced only in Avisynth 2.6.
Beginning from Avisynth 2.6 the YV16 format is officially supported and preferred because it is the same as YUY2+PlanarTools but in a standard Avisynth way.
I can imagine that a really old plugin is stuck with YV12 and (planarized) YUY2, I wonder which is that plugin which does not accept native YV16.

Selur
12th June 2020, 12:00
Okay, I'll simply drop PlanarTools then. :)

real.finder
12th June 2020, 12:10
It's used in AnimeIVTC and by proxy in QTGMC (since that nowadays uses parts of AnimeIVTC).
It's not 'required', as the script can be used without it, but it gives a speed boost for YUY2 processing.
-> I could live without it (authors of AnimeIVTC should adjust its script accordingly, but thats another issue), just wanted to let you know that it's not working, since you posted 'As there is no negative feedback on 3.6.1 test8 build'. :)


it's now in Zs_RF_Shared.avsi not AnimeIVTC

What speed boost? Planartools converts YUY2 to Planar-in-fake-YUY2 but in an unofficial (but widespread at those old times) way. Because YV16 (planar 4:2:2) was introduced only in Avisynth 2.6.
Beginning from Avisynth 2.6 the YV16 format is officially supported and preferred because it is the same as YUY2+PlanarTools but in a standard Avisynth way.
I can imagine that a really old plugin is stuck with YV12 and (planarized) YUY2, I wonder which is that plugin which does not accept native YV16.

the speed boost is from YUY2 to YV16 and YV16 to YUY2, Planartools don't work with Planar-in-fake-YUY2

also there are EEDI2 still not work with yv16

pinterf
12th June 2020, 12:27
it's now in Zs_RF_Shared.avsi not AnimeIVTC

the speed boost is from YUY2 to YV16 and YV16 to YUY2, Planartools don't work with Planar-in-fake-YUY2

Sorry then I was misleading. Anyway I'm checking the speed difference. (and as such, I'll have to recompile for myself)

also there are EEDI2 still not work with yv16
Does it have any quality benefit vs. the others or it is just kept because old scripts reference to it?

real.finder
12th June 2020, 12:50
Does it have any quality benefit vs. the others or it is just kept because old scripts reference to it?

https://forum.doom9.org/showthread.php?p=1909570#post1909570

that why there are VS port of it

edit: QTGMC has both EEDI2 and EEDI3

pinterf
12th June 2020, 13:05
The fix was already done at chikuzen's repo in 2016, but there was no release then.

Speedwise I tested the 64 bit version with Avisynth+ 3.6.1 test8 (but I think it's irrelevant, the YUY2<->YV16 part is not changed for years)

Note that I had to put the to-from conversion into a 30x loop in order to do meaningful measurement. So even if this part is made double-speed, it probably won't affect the speed of any script in a measurable way.

AviSynth: 436 fps
Planartools: 310 fps (compiled out-of-the-box)

BlankClip(length=10000,pixel_type="YV16")
for (i=1, 30) {
/*
ConvertToYUY2()
ConvertToYV16()
*/
PlanarToPacked()
PackedToPlanar()
}

EDIT:
Readme says:
"This plugin is a set of filters that offerd converting packed(interleaved)
formats to planar formats and vice versa.
Avisynth2.6 has these already as internal filters, but those are a little
difficult to use, and optimization is insufficient."

kedautinh12
12th June 2020, 13:19
@pinterf can you updated eedi3 for HBD??

kedautinh12
12th June 2020, 13:20
Can anyone help me how contact to asd-g??

vcmohan
12th June 2020, 13:32
fftw3 is thread safe but I think each execution is internal-threaded. AviSynth+ is external multi threaded.

In other words, with prefetch(4), your downstream is calling 4 GetFrame() from you at the same time in 4 different threads, and for each call, you connect to fftw3 and do some transform.
Now if you set threads=2 for fftw plans, then you will end up with 4×2=8 concurrent threads, using up to 8 CPU "core"s.

Thanks for clarifying. By rereading the documentation I also realized it. Therefore it looks I shoud not try planning with number of threads and leave it to avisynth for creating threads and process.

@pinterf I remember to have seen somewhere the range of float values for chroma has been changed from 0 - 1.0 to -0.5 - 0.5. Now have I to affect this change in my plugins for 3.6 + ? What happens for pre 3.6?

pinterf
12th June 2020, 13:38
Thanks for clarifying. By rereading the documentation I also realized it. Therefore it looks I shoud not try planning with number of threads and leave it to avisynth for creating threads and process.

@pinterf I remember to have seen somewhere the range of float values for chroma has been changed from 0 - 1.0 to -0.5 - 0.5. Now have I to affect this change in my plugins for 3.6 + ? What happens for pre 3.6?
Float chroma is +/- 0.5 since years.

real.finder
12th June 2020, 13:58
btw, since there are discussion about internal multi-threading, is this https://forum.doom9.org/showthread.php?p=1777021#post1777021 forgotten? maybe plugin can see if it available then use it, if not (in case of avs 2.6 or old avs+) then it use it own mt method

edit: also here https://forum.doom9.org/showthread.php?p=1778346#post1778346

stax76
13th June 2020, 14:41
There is a compatibility issue:

https://github.com/staxrip/staxrip/issues/224

https://github.com/sorayuki/VSFilterMod

real.finder
13th June 2020, 20:14
There is a compatibility issue:

https://github.com/staxrip/staxrip/issues/224

https://github.com/sorayuki/VSFilterMod

even with https://forum.doom9.org/showthread.php?p=1914950#post1914950 ?

stax76
13th June 2020, 21:08
Sorry, not really tried it, staxrip uses 3.6.0.

edit:

I confirm that 3.6.1 test 8 fixes this issue, thank you!

StainlessS
14th June 2020, 22:15
Pinterf,
Maybe 2 bugs in VirtualDub.dll [LoadVirtualDubPlugin] :- https://forum.doom9.org/showthread.php?p=1915630#post1915630

See 1st post of that thread for vdub vdf plugins.

StainlessS
15th June 2020, 13:15
Further to above,
Current path relative as below fails with error 0x7e, needs explicit full path to work eg ""D:\VDUB\ccd_32bit.vdf""

LoadVirtualdubPlugin(".\ccd_32bit.vdf", "_VD_CCD", preroll) # Change Path to VDF : fails with error 0x7e, needs full path


It might/probably work on WXP, but not W7+ (Vista unknown).

stax76
15th June 2020, 14:19
In portable mode is it possible to set a plugin auto load folder? Couldn't find anything in the wiki.

Groucho2004
15th June 2020, 14:25
In portable mode is it possible to set a plugin auto load folder? Couldn't find anything in the wiki.
What do you mean by 'portable mode'?

Edit - Have you tried AddAutoloadDir()?

stax76
15th June 2020, 14:32
What do you mean by 'portable mode'?

Edit - Have you tried AddAutoloadDir()?

That's what I was looking for but couldn't find, thanks.

Reel.Deel
15th June 2020, 14:35
Hi pinterf,

Quick question, why does ShowY/U/V default to RGB64? Should it default to the same colorspace as the input?

ColorBars(pixel_type="YUV420P16")
ShowY()
Info()

pinterf
15th June 2020, 14:49
Hi pinterf,

Quick question, why does ShowY/U/V default to RGB64? Should it default to the same colorspace as the input?

ColorBars(pixel_type="YUV420P16")
ShowY()
Info()
Probably because original ShowRed/Green/Blue ones
http://avisynth.nl/index.php/ShowAlpha
filled a mono-color RGB32 by default.
Channel extractions for this command works like this.

Or you can use then ExtractX family.

LigH
15th June 2020, 17:06
What do you mean by 'portable mode'?

Probably just having the avisynth.dll in the application's directory, without having it installed in the system (including all registry preparations for default plugin directories)...

Something similar to MeGUI using its own copy.

Selur
15th June 2020, 17:17
btw. is there a way to tell Avisynth not to autoload stuff and just use the plugins&co explicitly loaded?

qyot27
15th June 2020, 17:25
ClearAutoloadDirs()

Selur
15th June 2020, 17:28
Cool! Thanks! :)

pinterf
15th June 2020, 17:43
Meanwhile I have cleaned up the changes up to test8 and commited to the central repo.
Then I think it's documentation time, including filter SDK. Since the online docs are much more updated than existing offline one, I don't know which one would be better to start with. Backport online versions? Much time. Do rst version only from SDK docs?

Reel.Deel
15th June 2020, 17:53
Probably because original ShowRed/Green/Blue ones
http://avisynth.nl/index.php/ShowAlpha
filled a mono-color RGB32 by default.
Channel extractions for this command works like this.

Or you can use then ExtractX family.

Alright, thanks for the clarification. I'll update the wiki. I guess for that reason is that it only accepts 8 or 16 bit input. I thought it worked more like UToY/8, where the output is always Y/YUV.

***EDIT***

Meanwhile I have cleaned up the changes up to test8 and commited to the central repo.
Then I think it's documentation time, including filter SDK. Since the online docs are much more updated than existing offline one, I don't know which one would be better to start with. Backport online versions? Much time. Do rst version only from SDK docs?

I may be able to help with that, long ago I started updating some of the offline docs. But the wiki is far ahead, although it still needs much work to be up-to-date.

Personally, I think its better to bring up-to-date the online docs, and then down the road update the offline docs.

I'm actually starting on a SetFilterMTMode wiki page ATM. I have mainly maintained the external filters section, but I think its time to dedicate some time into avs+ documentation :).

qyot27
15th June 2020, 19:11
One thing for the Wiki docs: as with the list of x64 plugins, it might also be a good idea to start tracking which plugins have been ported to other OSes and CPU architectures, in order to try and stay ahead of it.

markiemarcus
16th June 2020, 04:04
Should AvisynthShader be working in test8? Or is it one for the list to be rebuilt? With test8 I'm still getting the same system exception as mentioned on the first page.

qyot27
16th June 2020, 05:22
https://forum.doom9.org/showthread.php?p=1909884&highlight=avisynthshader#post1909884

Myrsloik
16th June 2020, 11:29
Is there any way to signal that an audio track is 20 bits in the current api? If not, will some way to do so be added?

And what's the current stance on 24 bit audio. Should it be used or simply padded to 32 bits?

StainlessS
16th June 2020, 11:40
Kludges/signals currently supported in script
http://avisynth.nl/index.php/Internal_functions#OPT_UseWaveExtensible

EDIT:

OPT_AllowFloatAudio

global OPT_AllowFloatAudio = true ## default false
Float audio is converted to 16 bit when frameserving through ACM, unless OPT_AllowFloatAudio is set to true
(this option enables WAVE_FORMAT_IEEE_FLOAT audio output[1]). In that case the audio is kept as it is.
When accessing AviSynth directly (like MeGUI, BeHappy or ffmpeg do for example), there is no automatic conversion.

The automatic conversion is done for clients that cannot handle Float audio (in the old days most of them couldn't).
Note conversion takes place after the script processing is finished. Float audio is always allowed within the script.

OPT_UseWaveExtensible

global OPT_UseWaveExtensible = true ## default false
This option enables WAVE_FORMAT_EXTENSIBLE audio output. The default is WAVE_FORMAT_EX.
Note: The default DirectShow component for .AVS files, "AVI/WAV File Source", does not correctly implement WAVE_FORMAT_EXTENSIBLE processing,
so many application may not be able to detect the audio track. There are third party DirectShow readers that do work correctly.
Intermediate work files written using the AVIFile interface for later DirectShow processing will work correctly if they use the DirectShow "File Source (async)"
component or equivalent.

OPT_dwChannelMask

global OPT_dwChannelMask(int v) v2.60
This option enables you to set ChannelMask. It overrides WAVEFORMATEXTENSIBLE.dwChannelMask[[2] which is set according to this table

0x00004, // 1 -- -- Cf
0x00003, // 2 Lf Rf
0x00007, // 3 Lf Rf Cf
0x00033, // 4 Lf Rf -- -- Lr Rr
0x00037, // 5 Lf Rf Cf -- Lr Rr
0x0003F, // 5.1 Lf Rf Cf Sw Lr Rr
0x0013F, // 6.1 Lf Rf Cf Sw Lr Rr -- -- Cr
0x0063F, // 7.1 Lf Rf Cf Sw Lr Rr -- -- -- Ls Rs



EDIT: What I wrote in TwriteAVI docs, musta been based on experimentation

# For Float/WaveExtensible player eg MPC-HC (Else comment out below if Player not capable)
Global OPT_UseWaveExtensible = (AudioChannels>2||AudioBits>16) # If more than 2 channels or > 16 bit, set true (Also Float, ie > 16 bits).
Global OPT_AllowFloatAudio = (IsAudioFloat) # Must be set true to play in eg Media Player Classic - Home Cinema

EDIT: In avs, can use either RT_GetProcessName() or SI_ProcessName() to find name of app using Avisynth, and switch on above signals selectively for eg MPC-HC
or other player/app.

tebasuna51
16th June 2020, 12:46
Is there any way to signal that an audio track is 20 bits in the current api? If not, will some way to do so be added?

And what's the current stance on 24 bit audio. Should it be used or simply padded to 32 bits?

Of course 24 bit int can be used without problems but some functions don't support it. See Audio processing filters (http://avisynth.nl/index.php/Internal_filters), the filters than need some process works better in float format.
The precission of 24 int is, more or less, the same than 32 float (24 bits for mantissa) then I can understand "...simply padded to 32 bits" 32 bits int is not used normally.

20 bits can't be used inside AviSynth but in WAVE_FORMAT_EXTENSIBLE (http://www-mmsp.ece.mcgill.ca/Documents/AudioFormats/WAVE/Docs/multichaudP.pdf) header you can use the field wValidBitsPerSample (http://www-mmsp.ece.mcgill.ca/Documents/AudioFormats/WAVE/WAVE.html), but you can't save space because the samples must have 3 bytes (24 bits).
The most common way is put the last bits to 0 (I don't know any soft than read the field wValidBitsPerSample or use it)