Log in

View Full Version : FlipVertical and New BitBlt


Pages : [1] 2 3

ARDA
25th August 2015, 16:09
This is an update and different development for flipvertical, at least one part of it
that can work in place and also use avx instruction in new machines.
To avoid conflict names you must use as;

Fvertcal()

If you have my old flips.dll in your avisynth plugin folder you should replace it by
this new Vertical.dll

But actually this update was an excuse to develop a new bitblt, something I started many
years ago and has been sleeping in my disks and changing from one machine to another at least
for the last eight years, and as I never arrive to finish this project, I release it now the
way it is.
This new bitblt has only been tested in this plugin and others of my own use, never tested
deeply as a substitute of the internal one, only a few tests, so I cannot guarantee for now
full compatibility and free of bugs. It makes use of sse2, Ssse3 and avx instructions depending
on the machine on which is running.

This project includes four files from Agner Fog's libraries, cachesize32.asm, cputype32.asm,
instrset32.asm, unalignedfaster32.asm and some slightly modified subroutines from memcpy32.asm
You can find them in http://www.agner.org/optimize/asmlib.zip
All original Agner Fog's sources are also included in this file

Version 1.0 Fvertcal.7z (https://mega.nz/#!tI8jwYBC!PQdhAO9SEhNw9WSSNTqU_t-mgwY5Dkd-9C5AVlfNgjg)
Version 1.0 Fvertcal.zip (https://mega.nz/#!QNll3DxY!bYqD-0bJwlbdgFJUMjixCAcmytcAzI6tnXKCScC1YeQ)

Version 1.01 Fvertcal.7z (https://mega.nz/#!UVtgiRAR!dwBcEE9h2VshPswxmz5wzrVZFnb7WfNV5X8OAXv7clY)

Version 1.002 Fvertcal.dll (https://mega.nz/#!FFdW0ZRK!_stE39sFhzDjMlnB_vI7aEfHq8KEroH5adkxqRqfCr0)

Version 1.003 Fvertcal.dll (https://mega.nz/#!1EMXRZoS!6co0as92JfKA-ot5xyOY0a_sz3ugtsWCFAPi2AuZyO0)

Version 1.004 Fvertcal.dll (https://mega.nz/#!hVtShDAY!305YLuXYMoL_pkbiXRSvudnh30i2KKuEBK8knhC68ug)

Version 1005 Fvertical.dll (https://mega.nz/#!RFdRHaKI!qa15JjN58CuiPlIAu2m6H-sJFDwkfphAXq5ghNg-Qh8)


I hope this can be usefull
ARDA

Groucho2004
25th August 2015, 16:32
Quick test on my i5-2500K (Sandy Bridge):

Script:
blankclip(length = 1000, width = 5000, height = 3000, color=$005B8B).killaudio().assumefps(50, 1)
#flipvertical()
#fvertical()


Result with "flipvertical()"
[Runtime info]
Frames processed: 1000 (0 - 999)
FPS (min | max | average): 124.8 | 148.5 | 141.8
Memory usage (phys | virt): 121 | 120 MB
Thread count: 1
CPU usage (average): 24%
Time (elapsed): 00:00:07.050


Result with "fvertical()"
[Runtime info]
Frames processed: 1000 (0 - 999)
FPS (min | max | average): 121.3 | 141.3 | 135.9
Memory usage (phys | virt): 121 | 120 MB
Thread count: 1
CPU usage (average): 23%
Time (elapsed): 00:00:07.360


This is on XP, so no AVX optimizations used.

ARDA
25th August 2015, 16:42
If you have any doubt about the performance of any filter, I propose the following script

MPEG2Source("your source")
# or any source you like and use always the same to get a little more accurate benchmarks
# and test always the same frames each time. 9000 frames it is a good quantity for this script.

#TemporalSoften(4,8,8,15,2) # use this line to force a non writable src and test when a new video frame
# is created by your filter or not. It is just an example.

AvsTimer(frames=1000, name="ANYONE",type=3, frequency=x?, total=false, quiet=true)# use your cpu frequency

# Put here your filter to benchmark

#flipvertical()
#fvertical()

AvsTimer(frames=1500 ,name="ANYONE",type=3, frequency=x?, difference=1, total=false)# use your cpu frequency

Open the scipt in virtualdub, set direct stream copy, set an initial frame and an end frame.
Open debugview(google), set a filter highlight in debugview, in this example *ANYONE*
Go back to virtualdub and Run video analysis pass. You will see in debug view windows the results every 1500 frames.

If anyone knows and wants to propose any other more accurate method to benchmark, please post
here to discuss it.

I hope this can be usefull
ARDA

ARDA
25th August 2015, 16:46
@Groucho2004

The variation that your benchmark shows is too small, and your test is measuring blanckclip as well, and the efect it has on memory
Please try the method I propose and tell me what results you have

Thanks ARDA

Groucho2004
25th August 2015, 16:51
If you have any doubt about the performance of any filter, I propose the following script

MPEG2Source("your source")
# or any source you like and use always the same to get a little more accurate benchmarks
# and test always the same frames each time. 9000 frames it is a good quantity for this script.

#TemporalSoften(4,8,8,15,2) # use this line to force a non writable src and test when a new video frame
# is created by your filter or not. It is just an example.

AvsTimer(frames=1000, name="ANYONE",type=3, frequency=x?, total=false, quiet=true)# use your cpu frequency

# Put here your filter to benchmark

#flipvertical()
#fvertical()

AvsTimer(frames=1500 ,name="ANYONE",type=3, frequency=x?, difference=1, total=false)# use your cpu frequency

Open the scipt in virtualdub, set direct stream copy, set an initial frame and an end frame.
Open debugview(google), set a filter highlight in debugview, in this example *ANYONE*
Go back to virtualdub and Run video analysis pass. You will see in debug view windows the results every 1500 frames.

If anyone knows and wants to propose any other more accurate method to benchmark, please post
here to discuss it.

I hope this can be usefull
ARDA
I measured it with AVSMeter. Its timer is very accurate (particularly considering the timer peculiarities with multi-core CPUs) and I can't see the advantage in using AVSTimer for such a simple script.

I used "blankclip" instead of a "real" source because it's extremely fast and does not add any overhead.

Groucho2004
25th August 2015, 16:59
@Groucho2004

The variation that your benchmark shows is too small, and your test is measuring blanckclip as well, and the efect it has on memory
Please try the method I propose and tell me what results you have

Thanks ARDA
How about you post some results?

ARDA
25th August 2015, 17:27
In my haswell laptop. intel family 6 model 45h
Test done with the above method described.
with a size clip of 5000 x 3000 (Y8)
I will be doing more tests but please give some time.

with avstimer Fvertical()
VirtualDub.exe [91497] ANYONE = 302 fps
VirtualDub.exe [92997] ANYONE = 308 fps
VirtualDub.exe [94497] ANYONE = 309 fps
VirtualDub.exe [95997] ANYONE = 306 fps
VirtualDub.exe [97497] ANYONE = 289 fps
VirtualDub.exe [98997] ANYONE = 305 fps

with avstimer Flipvertical()
VirtualDub.exe [91499] ANYONE = 263 fps
VirtualDub.exe [92999] ANYONE = 268 fps
VirtualDub.exe [94499] ANYONE = 270 fps
VirtualDub.exe [95999] ANYONE = 270 fps
VirtualDub.exe [97499] ANYONE = 270 fps
VirtualDub.exe [98999] ANYONE = 268 fps

Thanks ARDA

Groucho2004
25th August 2015, 18:04
@Groucho2004

The variation that your benchmark shows is too small, and your test is measuring blanckclip as well, and the efect it has on memory
Please try the method I propose and tell me what results you have

Thanks ARDA
I get the same results with your method but only when I use the default frequency of my CPU (3300 MHz). I actually have it overclocked to 4000 MHz.
AvsTimer obviously uses the rdtsc instruction to measure time based on the CPU time stamp but this is highly unreliable, especially with modern CPUs.

ARDA
25th August 2015, 23:05
AvsTimer obviously uses the rdtsc instruction to measure time based on the CPU time stamp
but this is highly unreliable, especially with modern CPUs.

Extracted from avstimer docs:

The default method type=2 is based on the windows functions GetThreadTimes,
which measures the time the filter chain spends within the thread, by which is
it is called. This is the most accurate method as long as no other threads are
used by the filter chain. Currently I know of no example which violates this
assumption. However, as hyperthreading becomes more and more fashionable times
may change. If one uses the option type=1, then time is measured with GetProcessTimes.
Then the time of the process, which runs the Avisynth script, is measured,
while the process is executing the filter chain. However, some threads of this
process, which have nothing to do with the filters, but run parallel may
artificially reduce the frame rate. If type=0 or type=3 is used, then instead of
process or thread time the absolute time is taken. Then also other processes may
influence the frame rates to the downside. If type=0 then the function
QueryPerformaceCounter is used, if type=3 then the cpu instruction RDTSC is used.
type=3 has certainly the smallest overhead, but during initialisation 1 second is
necessary to determine the cpu frequency and on some notebooks the cpu frequency
may change over time obliterating all the results. To avoid the delay one may
also specify the cpu frequency with the frequency option. This must happen with
the first type=3 timer or any other timer befor the first type=3 timer otherwise
the frequency option is ignored. Thus AvsTimer(type=3, frequency= 1300) defines
a type= 3 timer for a cpu with 1300 MHZ. One can get the exact cpu frequency by
running a type= 3 timer without the frequency option. Then the exact cpu frequency
is displayed in the debugview window. Timers, which are paired together by the
difference option, shouldbe of the same type, otherwise the results do not make
sense and may even yield negative frame rates. Timers of type!= 2 have an
additional advantage. With such timers the frame rate of the entire process
running the script - we call this the total frame rate - can be measured and
is displayed by default.
Yes in the method I proposed, type=3 difines that rdtsc wil be used, if you
prefer QueryPerformaceCounter counter use type=0. You will get different results
but almost sure with the same distance between them.
Anyway for more accurate tests we should have to set real time priority and set
a thread affinity in the source plugin code, but that is not real life and I think
it wouldn't run under Windows XP(not sure)
There are a lot of academic discussion here and there all over the net about which is
the most accurate method to benchmark codes, I wouldn't like this thread become
about this subject.
I did not do the benchmarks with the example in RGBB32 cause it would take to much time
and with this resolution(5000x3000) new bitblt is also applied with non temporal stores.
In my machine and with a y8 clip here are the results;

Source= 5000x3000 (Y8)
AvsTimer(frames=1000, name="ANYONE",type=0, frequency=1700, total=false, quiet=true)
fvertical()
AvsTimer(frames=1500 ,name="ANYONE",type=0, frequency=1700, difference=1, total=false)

Use type=0 QueryPerformaceCounter
VirtualDub.exe AvsTimer 0.8.1
VirtualDub.exe AvsTimer 0.8.1
VirtualDub.exe [91499] ANYONE = 306 fps
VirtualDub.exe [92999] ANYONE = 305 fps
VirtualDub.exe [94499] ANYONE = 305 fps
VirtualDub.exe [95999] ANYONE = 305 fps
VirtualDub.exe [97499] ANYONE = 310 fps
VirtualDub.exe [98999] ANYONE = 310 fps

Use type=2 GetThreadTimes
VirtualDub.exe [91499] ANYONE = 305 fps
VirtualDub.exe [92999] ANYONE = 317 fps
VirtualDub.exe [94499] ANYONE = 311 fps
VirtualDub.exe [95999] ANYONE = 323 fps
VirtualDub.exe [97499] ANYONE = 331 fps
VirtualDub.exe [98999] ANYONE = 313 fps

Use type=3 RDTSC
VirtualDub.exe [91497] ANYONE = 302 fps
VirtualDub.exe [92997] ANYONE = 308 fps
VirtualDub.exe [94497] ANYONE = 309 fps
VirtualDub.exe [95997] ANYONE = 306 fps
VirtualDub.exe [97497] ANYONE = 289 fps
VirtualDub.exe [98997] ANYONE = 305 fps

************************************************************************************

Source= 5000x3000 (Y8)
AvsTimer(frames=1000, name="ANYONE",type=0, frequency=1700, total=false, quiet=true)
flipvertical()
AvsTimer(frames=1500 ,name="ANYONE",type=0, frequency=1700, difference=1, total=false)

Use type=0 QueryPerformaceCounter
VirtualDub.exe [91499] ANYONE = 262 fps
VirtualDub.exe [92999] ANYONE = 267 fps
VirtualDub.exe [94499] ANYONE = 267 fps
VirtualDub.exe [95999] ANYONE = 266 fps
VirtualDub.exe [97499] ANYONE = 267 fps
VirtualDub.exe [98999] ANYONE = 267 fps

Use type=2 GetThreadTimes
VirtualDub.exe [91499] ANYONE = 261 fps
VirtualDub.exe [92999] ANYONE = 275 fps
VirtualDub.exe [94499] ANYONE = 274 fps
VirtualDub.exe [95999] ANYONE = 268 fps
VirtualDub.exe [97499] ANYONE = 264 fps
VirtualDub.exe [98999] ANYONE = 284 fps

Use type=3 RDTSC
VirtualDub.exe [91499] ANYONE = 263 fps
VirtualDub.exe [92999] ANYONE = 268 fps
VirtualDub.exe [94499] ANYONE = 270 fps
VirtualDub.exe [95999] ANYONE = 270 fps
VirtualDub.exe [97499] ANYONE = 270 fps
VirtualDub.exe [98999] ANYONE = 268 fps


All above test shows an increase in performance of around 18% for flip vertical
In the conditions of a Y8 clip of 5000*3000 the plugin is using the new bitblt
by using non temporal stores, at least in my machine in which the largest cache
is a L3 of 3MB.
Under other conditions the difference can arrive till 30% or more; maybe in a few days
if I have time I will published more tests.

Thanks ARDA

jpsdr
26th August 2015, 08:44
The link for asmlib.zip is not working, at least for me.

ARDA
26th August 2015, 09:40
Try again please

jpsdr
26th August 2015, 11:46
It's working now.

EDIT :
Very interesting this asmlib !!!!
I didn't know about it, time to update all my projects...:D

:thanks:

ARDA
26th August 2015, 16:53
Very interesting this asmlib !!!!
I didn't know about it, time to update all my projects...

Happy you find something usefull.
If your projects include something relative to new bitblt or memcpy in avisynth I
encourage you to include my new source, and improve it if you find something wrong, anyway it
is a good idea to read all manuals in Agner Fog's page and mainly the assembler optimization.

Thanks ARDA

jpsdr
26th August 2015, 18:29
If your projects include something relative to new bitblt or memcpy in avisynth I
encourage you to include my new source, and improve it if you find something wrong


Big problem is that i'm absolutely not an yasm guy...:o
Other problem is that your code seems 32 bits only (because i've tried to take a look to find this new bitblt...:D).
So, unless there is something i'm more able to understand, i think for now i'll stay only with asmlib and allready build libraries.

ARDA
26th August 2015, 22:11
Big problem is that i'm absolutely not an yasm guy...
Other problem is that your code seems 32 bits only (because i've tried to take a look to find
this new bitblt...).
So, unless there is something i'm more able to understand, i think for now i'll stay only with
asmlib and allready build libraries.
Yes, all this project is 32bits only, new bitblt is all in BitBlt_SSE2_avs.asm file,
it is in the zip(see first post)
If you want a bitblt for 64 bits don't expect it soon from my side.
The day we have an avisynth for 64bits stable, faster than 32 bits and
reliable maybe I will think about it.
If I donnot remember wrong assembler codes in asmlib project are all
in yasm/nasm sintax it would be a good idea start looking at them without fear,
if you intend taking advantage of them. What a wonderful word is open source!

Thanks ARDA

Reel.Deel
26th August 2015, 23:52
The day we have an avisynth for 64bits stable, faster than 32 bits and reliable maybe I will think about it.


Sounds a lot like AviSynth+ r1576 :D.

ARDA
27th August 2015, 13:12
Source= 1920x1080 (Y8)
AvsTimer(frames=1000, name="ANYONE",type=0, frequency=1700, total=false, quiet=true)
flipvertical()
AvsTimer(frames=1500 ,name="ANYONE",type=0, frequency=1700, difference=1, total=false)

Use type=0 QueryPerformaceCounter
VirtualDub.exe [91498] ANYONE = 2163 fps
VirtualDub.exe [92998] ANYONE = 2263 fps
VirtualDub.exe [94498] ANYONE = 2283 fps
VirtualDub.exe [95998] ANYONE = 2298 fps
VirtualDub.exe [97498] ANYONE = 2301 fps
VirtualDub.exe [98998] ANYONE = 2305 fps

Use type=2 GetThreadTimes
VirtualDub.exe [91498] ANYONE = 2595 fps
VirtualDub.exe [92998] ANYONE = 2667 fps
VirtualDub.exe [94498] ANYONE = 2400 fps
VirtualDub.exe [95998] ANYONE = 2233 fps
VirtualDub.exe [97498] ANYONE = 2909 fps
VirtualDub.exe [98998] ANYONE = 2182 fps

Use type=3 RDTSC
VirtualDub.exe [91499] ANYONE = 2047 fps
VirtualDub.exe [92999] ANYONE = 2272 fps
VirtualDub.exe [94499] ANYONE = 2267 fps
VirtualDub.exe [95999] ANYONE = 2259 fps
VirtualDub.exe [97499] ANYONE = 2265 fps
VirtualDub.exe [98999] ANYONE = 2237 fps

Source= 1920x1080 (Y8)
AvsTimer(frames=1000, name="ANYONE",type=0, frequency=1700, total=false, quiet=true)
fvertical()
AvsTimer(frames=1500 ,name="ANYONE",type=0, frequency=1700, difference=1, total=false)

Use type=0 QueryPerformaceCounter
VirtualDub.exe [91498] ANYONE = 4825 fps
VirtualDub.exe [92998] ANYONE = 4801 fps
VirtualDub.exe [94498] ANYONE = 4804 fps
VirtualDub.exe [95998] ANYONE = 4819 fps
VirtualDub.exe [97498] ANYONE = 4870 fps
VirtualDub.exe [98998] ANYONE = 4853 fps

Use type=2 GetThreadTimes
VirtualDub.exe [91498] ANYONE = 6000 fps
VirtualDub.exe [92998] ANYONE = 5333 fps
VirtualDub.exe [94498] ANYONE = 5053 fps
VirtualDub.exe [95998] ANYONE = 3840 fps
VirtualDub.exe [97498] ANYONE = 5647 fps
VirtualDub.exe [98998] ANYONE = 6400 fps

Use type=3 RDTSC
VirtualDub.exe [91498] ANYONE = 4830 fps
VirtualDub.exe [92998] ANYONE = 4823 fps
VirtualDub.exe [94498] ANYONE = 4817 fps
VirtualDub.exe [95998] ANYONE = 4829 fps
VirtualDub.exe [97498] ANYONE = 4851 fps
VirtualDub.exe [98998] ANYONE = 4843 fps
These tests were done to test different kind of methods to measure performance under avstimer
These tests shows that fvertical is around 100% faster, in fact we should say that new fvertical
in place is faster than internal avisynth bitblt, so it is not a fair comparation, but
this was the one of the objectives of this plugin, to get better performance for flip vertical
when posible.
More tests soon.

Thanks ARDA

ARDA
27th August 2015, 20:42
Source= 720x576 (Y8)
AvsTimer(frames=1000, name="ANYONE",type=0, frequency=1700, total=false, quiet=true)
fvertical()
AvsTimer(frames=1500 ,name="ANYONE",type=0, frequency=1700, difference=1, total=false)

Use type=0 QueryPerformaceCounter
VirtualDub.exe [91498] ANYONE = 30549 fps
VirtualDub.exe [92998] ANYONE = 30837 fps
VirtualDub.exe [94498] ANYONE = 30766 fps
VirtualDub.exe [95998] ANYONE = 30768 fps
VirtualDub.exe [97498] ANYONE = 30690 fps
VirtualDub.exe [98998] ANYONE = 30673 fps

Use type=2 GetThreadTimes
VirtualDub.exe [91498] ANYONE = 24000 fps
VirtualDub.exe [92998] ANYONE = 24000 fps
VirtualDub.exe [94498] ANYONE = 24000 fps
VirtualDub.exe [95998] ANYONE = 16000 fps
VirtualDub.exe [97498] ANYONE = 32000 fps
VirtualDub.exe [98998] ANYONE = 48000 fps

Use type=3 RDTSC
VirtualDub.exe [91498] ANYONE = 30725 fps
VirtualDub.exe [92998] ANYONE = 30835 fps
VirtualDub.exe [94498] ANYONE = 30936 fps
VirtualDub.exe [95998] ANYONE = 30952 fps
VirtualDub.exe [97498] ANYONE = 30488 fps
VirtualDub.exe [98998] ANYONE = 30806 fps
Source= 720x576 (Y8)
AvsTimer(frames=1000, name="ANYONE",type=0, frequency=1700, total=false, quiet=true)
flipvertical()
AvsTimer(frames=1500 ,name="ANYONE",type=0, frequency=1700, difference=1, total=false)

Use type=0 QueryPerformaceCounter
VirtualDub.exe [91497] ANYONE = 9094 fps
VirtualDub.exe [92997] ANYONE = 12647 fps
VirtualDub.exe [94497] ANYONE = 12826 fps
VirtualDub.exe [95997] ANYONE = 13012 fps
VirtualDub.exe [97497] ANYONE = 12892 fps
VirtualDub.exe [98997] ANYONE = 12935 fp

Use type=2 GetThreadTimes
VirtualDub.exe [91498] ANYONE = 16000 fps
VirtualDub.exe [92998] ANYONE = 8727 fps
VirtualDub.exe [94498] ANYONE = 24000 fps
VirtualDub.exe [95998] ANYONE = 8727 fps
VirtualDub.exe [97498] ANYONE = 12000 fps
VirtualDub.exe [98998] ANYONE = 10667 fps

Use type=3 RDTSC
VirtualDub.exe [91498] ANYONE = 12403 fps
VirtualDub.exe [92998] ANYONE = 13077 fps
VirtualDub.exe [94498] ANYONE = 12927 fps
VirtualDub.exe [95998] ANYONE = 12930 fps
VirtualDub.exe [97498] ANYONE = 12985 fps
VirtualDub.exe [98998] ANYONE = 12993 fps
This resolution shows and increase performance of around 100%, is almost the same
condition than previous tests

Groucho2004
27th August 2015, 21:17
OK, I tested it properly now. In order to measure the very short time for each call of *vertical() I just call it several times. "colorbars()" is extremely fast and does not influence the results.

Here's the script:
colorbars(width = 1920, height = 1080, pixel_type = "yv12").killaudio().assumefps(25, 1).trim(0, 4999)
#test_flipvertical()
#test_fvertical()

function test_flipvertical(clip c)
{
last = c
flipvertical().flipvertical().flipvertical().flipvertical().flipvertical()
flipvertical().flipvertical().flipvertical().flipvertical().flipvertical()
return last
}

function test_fvertical(clip c)
{
last = c
fvertical().fvertical().fvertical().fvertical().fvertical()
fvertical().fvertical().fvertical().fvertical().fvertical()
return last
}

flipvertical:
Frames processed: 5000 (0 - 4999)
FPS (min | max | average): 195.1 | 201.1 | 199.1
Memory usage (phys | virt): 15 | 14 MB
Thread count: 1
CPU usage (average): 25%
Time (elapsed): 00:00:25.109

fvertical:
Frames processed: 5000 (0 - 4999)
FPS (min | max | average): 687.9 | 736.4 | 730.7
Memory usage (phys | virt): 12 | 12 MB
Thread count: 1
CPU usage (average): 25%
Time (elapsed): 00:00:06.843

Very impressive!

TheFluff
27th August 2015, 22:46
now benchmark it against a bitblt that simply uses a memcpy from a modern runtime instead

I suspect the only reason that this possible to optimize is that Avisynth's ~optimized~ bitblt is an ancient piece of garbage written for P4's and ancient Athlons, which doesn't really produce great results on modern CPU's. Agner Fog's memcpy implementation was - by his own benchmarks - only barely faster than Microsoft's back in 2008 (https://sourceware.org/ml/libc-help/2008-08/msg00007.html). Replacing Avisynth's bitblt with a wrapper around memcpy and compiling with a modern runtime (haha, who am I kidding, this is Avisynth) would probably speed it up a lot.

ARDA
27th August 2015, 23:13
@Groucho2004
I like the way you have done to reduce the effect of colorbars.
Glad to see you find it impressive, but that result is a little bit deceiving cause
several things

1) Fvertical with that script is working in place it does not apply the new bitblt
While flipvertical is always using internal bitblt that has wrong bypasses
cache for your sandybridge that I guess has at least 4 mb of L3 cache
so it is doing a non temporal store to a new frame created

2) As Fvertical is working in place(on source), after two or three iterations
all data will be in cache and the speed improvement will be giant
Unluckily your results are not really true in real life where you never call
10 times flipvertical, except you are doing an special effect.

To make the test most trustable you should include any filter that makes the source
unwritable, but anyway in the second call of fvertical it will be writable again
and the benchmark result will not be real either.
According to my experience more than 120% of increase is almost impossible

Thank you for the time spent. ARDA

ARDA
27th August 2015, 23:17
@TheFluff
All thlis filter was done as an excuse to develop a new bitblt where Agner Fog's code are adapted and included to work in avisynth
If you take a look in the code you will find a dedicated code of 4500 assebly lines with many explanations in comments
I hope you like it

Thanks ARDA

TheFluff
27th August 2015, 23:22
If you take a look in the code you will find a dedicated code of 4500 assebly lines with many explanations in comments

that's genuinely horrifying

ARDA
27th August 2015, 23:36
Sad to see You don't like my code

Thanks anyway ARDA

Groucho2004
27th August 2015, 23:55
Fvertical with that script is working in place it does not apply the new bitblt
You're right. Using just a single call we're back to the results I already reported. On XP, fvertical is slower than flipvertical, possibly because AVX instructions are not supported.

ARDA
28th August 2015, 00:11
You're right. Using just a single call we're back to the results I already reported. On XP, fvertical is slower than flipvertical, possibly because AVX instructions are not supported.

There must something wrong in my code, something that deviate to the wrong soubrutine in your machine, you should get at least 100% of increase in performance with that resolution except you had included something in your script that makes the source non writable , in that case you should find
an increase around 15%. I will take a look and see what I find.

Thanks ARDA

ARDA
28th August 2015, 00:23
[Script]
blankclip(length = 9000, width = 5000, height = 3000, color=$005B8B).killaudio().assumefps(50, 1)
#flipvertical()
fvertical()

[Clip info]
Number of frames: 9000
Length (hh:mm:ss.ms): 00:03:00.000
Frame width: 5000
Frame height: 3000
Framerate: 50.000 (50/1)
Colorspace: RGB32

[Runtime info]
Frames processed: 9000 (0 - 8999)
FPS (min | max | average): 21.62 | 86.07 | 76.91
Memory usage (phys | virt): 127 | 126 MB
Thread count: 1
CPU usage (average): 23%
Time (elapsed): 00:01:57.021

with AvsTimer Use type=3 RDTSC
VirtualDub.exe [91499] ANYONE = 79 fps
VirtualDub.exe [92999] ANYONE = 78 fps
VirtualDub.exe [94499] ANYONE = 79 fps
VirtualDub.exe [95999] ANYONE = 80 fps
VirtualDub.exe [97499] ANYONE = 76 fps
VirtualDub.exe [98999] ANYONE = 78 fps
[Script]
blankclip(length = 9000, width = 5000, height = 3000, color=$005B8B).killaudio().assumefps(50, 1)
flipvertical()
#fvertical()

[Clip info]
Number of frames: 9000
Length (hh:mm:ss.ms): 00:03:00.000
Frame width: 5000
Frame height: 3000
Framerate: 50.000 (50/1)
Colorspace: RGB32

[Runtime info]
Frames processed: 9000 (0 - 8999)
FPS (min | max | average): 19.27 | 81.19 | 71.75
Memory usage (phys | virt): 127 | 126 MB
Thread count: 1
CPU usage (average): 23%
Time (elapsed): 00:02:05.428

with AvsTimer Use type=3 RDTSC
VirtualDub.exe [91497] ANYONE = 73 fps
VirtualDub.exe [92997] ANYONE = 74 fps
VirtualDub.exe [94497] ANYONE = 74 fps
VirtualDub.exe [95997] ANYONE = 74 fps
VirtualDub.exe [97497] ANYONE = 74 fps
VirtualDub.exe [98997] ANYONE = 75 fps
Finally I had some time to make this test with a clip 5000 x 3000 in RGB32
As you can see fvertical is still faster, in this case only beetween 4% and 7%,
but this result is coherent with the size of the frame, in fact 20000 x 3000 bytes
cause is RGB32 (4 bytes for each pixel).
Anyway it seems to me that something is wrong I will take a look in the code to see
if I can get a little bit more performance.Besides that Grocuho2004's maachine is giving me
some headache, let's see what I find.
It is probably that with bigger sizes you will have similar results. It seems that
the example chosen is one of the worst conditions for this new bitblt.
When bitblt is applied en fvertical, results are always between 5% to 25% increase
in performance, depending on the maachine script etc.., which is actually the real
improvemnt in the new bitblt.

ARDA
28th August 2015, 01:06
[Script]
colorbars(width = 1920, height = 1080, pixel_type = "yv12").killaudio().assumefps(25, 1).trim(0, 8999)
#flipvertical()
fvertical()

[Clip info]
Number of frames: 9000
Length (hh:mm:ss.ms): 00:06:00.000
Frame width: 1920
Frame height: 1080
Framerate: 25.000 (25/1)
Colorspace: YV12

[Runtime info]
Frames processed: 9000 (0 - 8999)
FPS (min | max | average): 1090 | 2303 | 2077
Memory usage (phys | virt): 18 | 17 MB
Thread count: 1
CPU usage (average): 23%
Time (elapsed): 00:00:04.333
[Script]
colorbars(width = 1920, height = 1080, pixel_type = "yv12").killaudio().assumefps(25, 1).trim(0, 8999)
flipvertical()
#fvertical()

[Clip info]
Number of frames: 9000
Length (hh:mm:ss.ms): 00:06:00.000
Frame width: 1920
Frame height: 1080
Framerate: 25.000 (25/1)
Colorspace: YV12

[Runtime info]
Frames processed: 9000 (0 - 8999)
FPS (min | max | average): 618.8 | 1766 | 1557
Memory usage (phys | virt): 18 | 17 MB
Thread count: 1
CPU usage (average): 23%
Time (elapsed): 00:00:05.780
As I have not a SandyBridge with Windows XP so I have built a version that donnot use
Avx instructions to see what happens in my machine, tested your script but
with 9000 frames and with your own tool avsmeter. The results I get are that fvertical
is around 25% faster. That makes suspect that my code is wrong and is using
the wrong subroutines in your machine. Investigating!

Thanks ARDA

Groucho2004
28th August 2015, 08:45
One more time for comparison:
colorbars(width = 1920, height = 1080, pixel_type = "yv12").killaudio().assumefps(25, 1).trim(0, 99999)
#flipvertical()
#fvertical()


flipvertical: 3713
fvertical: 3261

ARDA
28th August 2015, 14:50
@Groucho2004

New bitblt is designed to detect some cpu characteristics and deviate to the
appropriate routines accordingly with the cpu on which is running.
After analyzing your scripts for the tests I gathered that Blankclip and colorbars
always return a non writable source, so with only one call fvertical will always apply
new bitblt, but when you call fvertical several times, from second time onward fvertical
will be done in place at least for normal resolutions(below 2 1/2 times largest cache ).
Then I can conclude definitely that there is a wrong selection of the routines for your
cpu within my new bitblt code. Something I will try to fix, but I need your help
for that. I hope you can give me the following data;

Cpu Vendor
Cpu Family
Cpu Model
Instructions set
Operating system
L1, L2, L3 sizes (think there is not L4 in your cpu)
Frequency(normal, and the one is running)

With that data I will try to know which routines should be used. Then if you agree
I will prepare some tests versions I will send you by PM to confirm and fix the selection
of routines for your cpu. If someone else has similar results Groucho20004 and a similar
machine,I ask you please put your results here and help us fix this bug

Thanks in advance. ARDA

Groucho2004
28th August 2015, 15:36
Cpu Vendor
Cpu Family
Cpu Model
Instructions set
L1, L2, L3 sizes
Info here (http://ark.intel.com/products/52210/Intel-Core-i5-2500K-Processor-6M-Cache-up-to-3_70-GHz)

Operating system
XP32_SP3

Frequency(normal, and the one is running)
3.3 GHz, oc to 4 GHz

ARDA
28th August 2015, 16:42
@Groucho2004
Thanks for the help, unluckily the intel page is a little poor in information
at least after a quick sight, but I think I'll manage with what I have.
While investigating problem with Groucho2004 cpu and my code I've made some small changes
that increase around 1% with some special care of prefetches values and loop size.
Please I ask everybody who has time, to test and post here the results
Version 1.01 Fvertcal.7z (https://mega.nz/#!UVtgiRAR!dwBcEE9h2VshPswxmz5wzrVZFnb7WfNV5X8OAXv7clY)

Groucho2004
28th August 2015, 17:10
Thanks for the help, unluckily the intel page is a little poor in information
at least after a quick sight, but I think I'll manage with what I have.
How about this (http://pastebin.com/FGtfi4i8)?

ARDA
28th August 2015, 17:19
Perfect thank you

ARDA
30th August 2015, 13:25
Working with the help of Groucho2004 we could figure out that the problem
of performance there is with new bilblt in his cpu was a wrong bypass cache
value, actually it was fixed in 50% of largest cache which is a thumb
rule, but avisynth gobbles up 1024kb of cache memory or more depending on
the script, that is why this value will be always a trade off
For all previously exposed I need volunteers to test those values in
different configurations; it is a boring task where many tests must be done.
(around 10).
The version to start test is 1.002
You can download dll in the link. New sources will be avaiable when version 1.1

Version 1.002 Fvertcal.dll (https://mega.nz/#!FFdW0ZRK!_stE39sFhzDjMlnB_vI7aEfHq8KEroH5adkxqRqfCr0)

ARDA
31st August 2015, 12:36
Some new results in Groucho2004's cpu
Intel i5-2500K (Sandy Bridge)3.3 GHz, oc to 4 GHz. L3 cache 6.0 MB
All the following tests were done with Fvertical version 1.002(see previous and first post)

#colorbars(width = 720, height = 576, pixel_type = "yv12").killaudio().assumefps(25, 1).trim(0, 99999)
#flipvertical() #15542 fps
#fvertical() #24528 fps

#colorbars(width = 1392, height = 992, pixel_type = "yv12").killaudio().assumefps(25, 1).trim(0, 99999)
#flipvertical() #5217 fps
#fvertical() #7322 fps

#colorbars(width = 1392, height = 1024, pixel_type = "yv12").killaudio().assumefps(25, 1).trim(0, 99999)
#flipvertical() #5053 fps
#fvertical() #5443 fps

#colorbars(width = 1920, height = 1080, pixel_type = "yv12").killaudio().assumefps(25, 1).trim(0, 99999)
#flipvertical() #3701 fps
#fvertical() #4069 fps

We shall still be tuning, but please I need volunteers;) I hope these results arouse the enthusiasm of good colleagues and come to help us to fine tuning this project.

Thanks in advance ARDA

TurboPascal7
31st August 2015, 13:18
Just wondering - have you ever tried measuring real-world performance improvements with your memcpy implementation? Maybe replacing internal BitBlt with it and running something more or less heavy like qtgmc?

ARDA
31st August 2015, 16:09
Just wondering - have you ever tried measuring real-world performance improvements with
your memcpy implementation? Maybe replacing internal BitBlt with it and running something
more or less heavy like qtgmc?


This is part of the first post of the thread

This new bitblt has only been tested in this plugin and others of my own use, never tested
deeply as a substitute of the internal one, only a few tests, so I cannot guarantee for now
full compatibility and free of bugs. It makes use of sse2, Ssse3 and avx instructions depending
on the machine on which is running.


To define real life performance is quite difficult , if we are measuring
bitblt-memcpy performance I have first to finish tuning most bypasses cache I can test,
with fvertical that in fact only test when a row loop is executed, other filters that make
direct use of bitblt or other special tools, that is why I am asking for volunteers to help.

I don't know qtgmc internals, maybe it does not use bitblt-memcpy at all, I should need
to study it. Anyway avisynth can create so complex and different chains that it is almost
imposible to preview and measure the use or not and/or the weight of bitblt-memcpy in general performance.
That could lead to conclude, is it worth to do faster assembler implementations?
Maybe better to leave compilers do the job, or maybe everytime we jump to a new
higher resolution we buy a new and faster cpu. There are a lot of academic discussion
all over in the net about it , I wouldn't like this thread becomes a discussion about
this subject. Mainly because it is more related to commercial politics of corporations
and ideology of Universities about how to prepare new software engineers
and definitely this is not the place for such a polemic.
I can only add that luckily old and some new avisynth developer always tried
to squeeze up the better performance possible in each step. I still remember
when my cpu was a thunderbird(2001?) with only Isse, and thanks to Steady-Sh0dan bitblt-memcpy
I could use it for many years .

Every filter or part of avisynth authors should take care of the performance of their work
Besides that when you measure the performance of one or another script, you will always
get a performance influenced by the slowest part of such script, which will hide the fastest part of it
Anyway it is quite obvious that bitblt-memcpy(weight??) is one of the steps that can influence in general
avisynth performance, but it is not the only one.

This implementation of bitblt-memcpy was done to use it in a plugin, for now
to integrate to avisynth it is a bit complex, cause there will be a lot of redundant parts
In spite of that I have made a few tests with a quick integration trying to see if
if I could detect some bugs, but din't do a deep research, it was not the purpose at this
stage of the development. Be patient, everything can arrive; nowadays Steady-Sh0dan bitblt
implementation has more than 10 years. Has anyone asked why so many years without
a new implementation?
For all above exposed for now I will focus to finish the work I am doing with Groucho2004
and other volunteers, and as I have few free time that will be enough for now.

I hope you find something usefull;)
Thanks ARDA

Myrsloik
1st September 2015, 22:45
I ported the optimized BitBlt in VapourSynth to avisynth and made a flippin' good plugin too!

Usage: FlipVFaster()

Link (https://dl.dropboxusercontent.com/u/73468194/FlipVFaster.7z)

ARDA
1st September 2015, 23:46
I ported the optimized BitBlt in VapourSynth and made a flippin' good plugin too!
Usage: FlipVFaster()


Happy to see you are trying to use it, anyway I will upload the new version, of
bitblt cause many bypasses cache has changed and you will be getting low performance
in some cpus. I don't have VapourSynth instaled so I cannot give you feedback in this case

This link is only new bitblt.asm for developers
Only BitBlt_SSE2_avs.asm (https://mega.nz/#!QQNxTKQQ!st_0m_gSkrnBABq46-oRKc6sK_J-omVaitRnRfZx3nY)

Soon I will upload Fvertical.dll V1.003 with more changes in cache bypass values
But I still need volunteers to test more cpus.

Thanks ARDA:rolleyes:

TheFluff
2nd September 2015, 15:34
I don't have VapourSynth instaled so I cannot give you feedback in this case

Read the post. It's an Avisynth plugin. Benchmarks welcome.

ARDA
2nd September 2015, 16:53
Read the post. It's an Avisynth plugin. Benchmarks welcome.

Sorry , quick read, I will do some benchmarks and publish here, but I donnot know if Myrsloik has updated BitBlt_SSE2_avs.asm. Let us wait
till he can confirm. I will also ask Myrsloik if he can release the code to see how he has done the integration, cause it is a little tricky.

@TheFluff
Maybe you can also post some benchmarks results, they will be welcome.:rolleyes:

Thanks ARDA

Myrsloik
2nd September 2015, 17:12
Sorry , quick read, I will do some benchmarks and publish here, but I donnot know if Myrsloik has updated BitBlt_SSE2_avs.asm. Let us wait
till he can confirm. I will also ask Myrsloik if he can release the code to see how he has done the integration, cause it is a little tricky.

@TheFluff
Maybe you can also post some benchmarks results, they will be welcome.:rolleyes:

Thanks ARDA

I didn't touch any of your asm. It's all original code from me.

ARDA
2nd September 2015, 17:29
I didn't touch any of your asm. It's all original code from me
I was asking if you updated the asm code with the link in this post ,it was specially released because of you
http://forum.doom9.org/showthread.php?p=1736739#post1736739
Besides that if you take a look to fvertical.cpp you will see that it need some extra calls previously like.

Pass_sizeframe((dstframesize)+(dstframesizeU)+(dstframesizeU));

I will publish a whole explanation about the architecture of this new bitblt and how to use it.

Thanks ARDA

ARDA
2nd September 2015, 17:53
@all developers

This version of bitblt-memcpy is still under heavy development, mainly cause the bypass values
relatives to each cpu must be fixed manually, I never could find a general formula, I would
ask to wait and help me with your cpus to find most exact possible value by doing some tests
like Groucho2004 has done. I release here fviertical. dll version 1.003 that I think it quite
near to be definitive(do benchmaks with it), after that I will release source code again

@all developers and users
Version 1.003 Fvertcal.dll (https://mega.nz/#!1EMXRZoS!6co0as92JfKA-ot5xyOY0a_sz3ugtsWCFAPi2AuZyO0)

Thanks ARDA

ARDA
2nd September 2015, 18:47
To discuss about bitlt-memcpy specifically please follow this new thread

http://forum.doom9.org/showthread.php?p=1736845#post1736845

And we stay here with all related with fvertical
Thnaks ARDA

TheFluff
2nd September 2015, 19:25
I was asking if you updated the asm code with the link in this post ,it was specially released because of you
http://forum.doom9.org/showthread.php?p=1736739#post1736739
Besides that if you take a look to fvertical.cpp you will see that it need some extra calls previously like.

Pass_sizeframe((dstframesize)+(dstframesizeU)+(dstframesizeU));

I will publish a whole explanation about the architecture of this new bitblt and how to use it.

Thanks ARDA

I guess we have to explain the joke since it apparently went completely over your head. Myrsloik hasn't looked at your code at all, he wrote his own flipvertical implementation using Vapoursynth's bitblt, which looks like this:
static inline void vs_bitblt(void *dstp, int dst_stride, const void *srcp, int src_stride, size_t row_size, size_t height) {
if (height) {
if (src_stride == dst_stride && src_stride == (int)row_size) {
memcpy(dstp, srcp, row_size * height);
} else {
const uint8_t *srcp8 = (const uint8_t *)srcp;
uint8_t *dstp8 = (uint8_t *)dstp;
for (size_t i = 0; i < height; i++) {
memcpy(dstp8, srcp8, row_size);
srcp8 += src_stride;
dstp8 += dst_stride;
}
}
}
}
It's probably faster than Avisynth 2.6's implementation and insignificantly slower than yours. If you were sane, you would have benchmarked that, but I don't think you have.

jpsdr
2nd September 2015, 21:49
I guess we have to explain the joke since... It's probably faster than Avisynth 2.6's implementation...

You've copied what i've done i nnedi... :D

inline void PlanarFrame::BitBlt(uint8_t *dstp,int dst_pitch,const uint8_t *srcp,int src_pitch,int row_size,int height)
{
if ((height==0) || (row_size==0)) return;

if ((height==1) || ((dst_pitch==src_pitch) && (src_pitch==row_size))) A_memcpy(dstp,srcp,(size_t)src_pitch*(size_t)height);
else
{
for (int y=0; y<height; y++)
{
A_memcpy(dstp,srcp,row_size);
dstp+=dst_pitch;
srcp+=src_pitch;
}
}
}


But you missed the case of height=1.
.... Ok, i'm going out... :p

jmac698
3rd September 2015, 05:10
fvertical:
Frames processed: 5000 (0 - 4999)
FPS (min | max | average): 98.98 | 159.3 | 145.9
Memory usage (phys | virt): 16 | 12 MB
Thread count: 1
CPU usage (average): 49%

Time (elapsed): 00:00:34.272

flipvertical:
Frames processed: 5000 (0 - 4999)
FPS (min | max | average): 18.97 | 49.62 | 45.19
Memory usage (phys | virt): 19 | 15 MB
Thread count: 1
CPU usage (average): 49%

Time (elapsed): 00:01:50.644

323% speedup, very impressive!

t7300@2GHz
fam 6 model f step b
mmx,sse,sse2,sse3,ssse3
l1 2x32k l2 4M
2c2t

benchmark as in
http://forum.doom9.org/showthread.php?p=1736148#post1736148

jmac698
3rd September 2015, 05:24
AviSynth+ 0.1 (r1779, MT, i386) (0.1.0.0)
Frames processed: 5000 (0 - 4999)
FPS (min | max | average): 15.85 | 49.96 | 45.00
Memory usage (phys | virt): 23 | 23 MB
Thread count: 3
CPU usage (average): 49%

Time (elapsed): 00:01:51.121

same speed as AviSynth 2.60, build:Mar 31 2015 [16:38:54] (2.6.0.6)