ZK12: Myth vs. Reality: Enhancing Proving Time in KZG-Backed Plonkish Systems for zkWASM - Sinka Gao
18 Oct 2024 · 53:33
Recorded at ZK12 in Lisbon, Sinka Gao of Delphinuslab challenges the assumption that KZG polynomial commitments are as slow on GPUs as they are on CPUs. Comparing a 64-bit zkWASM virtual machine against 32-bit STARK systems, Gao shows proving speeds around 13 seconds per million instructions across more than 140 opcodes, and argues that 64-bit execution traces often end up smaller than their 32-bit counterparts.
Speakers
Topics
Transcript
[Music] okay thanks for attending this um small workshop and and I hope that uh many of so and all of you already have some ideas about what is kdg backand proving systems and uh you know um there rumors or maybe uh benchmarks around there say that actually uh most of the CG backend circuit that return in circum halo2 or something else that is runs pretty slow in CPU right and today I'm going to introduce our way to
somehow um improve the performance but not in CPU but in our relatively expensive Hardware called GPU 490 to somehow bring the Benchmark uh bring the performance back to a level so that it can compete with some other um proving systems so um the agenda that I'm going to give today is I'm going to quickly go through uh what we are building and then um give you a map about the benchmarks between CPU and GPU and telling about uh what's makes so difference of optimization in GPU and how we do that and I will show a little bit about our progress on somehow bring about 30 to 50 proof uh speed increase on
transplanted kdg back end from CPU completely into GPU okay so let's start with uh our our VM so we are writing uh web assembly ckvm that is a CVM actually supports web assem execution and generate proof for the execution and so presumably you all know what web is and uh I give two um supplementary um on what whatam is that uh wam natively supports host applications and wam is extendable with um SD which are vector instructions and the way that we
handles the webam execution that we do a uh slice splitting of the full execution and then uh make full recursions on all the slice proof okay so what does that mean um that means uh we split the whole execution of web blist um let me show you for example um uh uh sorry um sorry I'm okay I'll show you uh a very I think simple example about
this is a web assembly code that actually has a front end written in Rust it somehow does a very simple harh on about three megabytes B code right nothing special I just compile that one into a web assembly okay so after the compilation you get this image. web assembly after and after we do uh what OPD is somehow remove all the unrelevant run HS from this image web assembly into output web assembly and let's recap what w looks like it is
um something like this so sorry what it what I sorry I did not install the the decoder of the web assembly but um the idea that it has um about 148 instructions likes um that is the whole instruction set about web assembly and um so and it's about 64bit worldwide so that means you every
operant you have handling with is 64bit and we we stick with this 64-bit setup for a while and we're using um kdg backend which supports 352 bits so that we can perform multiplication for 64 bits uh in two or three uh cells and because we split them into different slices we have to um proving um each slice Tru to somehow actually make sure that the execution within single slid is correct um and this looks like this uh let's prove this by run the web assembly
and looks the proving looks like this um so because now I'm using uh GPU versions that actually provides by IO so this a intermediate result that we have for each proof and what it does is that actually does the CI set up and then prove each slid because this one has about 360 million instructions right so it be split into four slies right and each slice we draw proof and we'll see that we spend some time about four to five seconds on the commitment and which is MSM and then we sorry um and we see that
the final Pro time is about uh for each slce it's about 10 to 12 right and we repeat that for four times okay and but after this we did not actually get the whole proof of the execution because we only get the slies proofs okay so uh there's last last slide which I will actually um I I I'll quit that because we're not going to verify that okay and this will give us all these small sze grps underneath right and these are not
connected so so that means when we do have this U slice proofs we have to make sure that the memory uh continues between different slides and uh there are many ways to do that we we happens to choose a very old school technology which is actually comparing the memory column the the commitment of the memory column so that means uh for each proof in the batching we make sure that the commitment of the memory column for the previous slides is equal to the pre-image of the next proof uh of the memory column okay so and
because um because every time when you B approve you need a universal appr that actually generates a CIS circuit right which is the verification algorithm that return the another circuit and then this has to be generic that means every time you cannot change the V key otherwise you will get different proofs uh or V key setup for each R you will start uh we still happen to choose a old school version of this recursion circuit it's it's a full recursion so that we actually encoding the pairing um algorithm into this circuit so then every time we do a circuit but
there are drawbacks of this because every time you do a full recursion you have to wait for the previous recursion to finish to actually uh finalize but the good news is that um although there are lot of um Benchmark externally says that kdg recursion is slow but thanks to uh the algorithm optimization from J apps this now can be reduced to about 3 to 5 seconds so that means we we can somehow um I'm this talk actually elaborate a little bit about this recursion circuit as well but the idea is that we use a full recursion and we do the recursion all the way through to
the final proof and just try to give some feeling about how to rec cion does it is um the recursion because this will actually uh uses the instance data that we generate before and every time so sorry this is done in CP this should only be done work but because I'm writing a c test script this has been done many times so what you know is that every Ro it takes a few seconds that's about 4 seconds to recursion and then you just repeat this process so that in the end you get a fully batched um proof from beginning to end and because
for because for each each R uh you have to adding a recursion circuit proving here so the the total proving time um is not only the proving time of the guest circuit it's should be a sum of the um whole power in one GPU that is about um if you're using uh open source um GPU is about 12 to 13 seconds plus uh 4 seconds so it's it needs about 17 seconds to generate one mil structures but that actually Benchmark contains
recursion right so the not because there are lot of VM outside they only comparing about the proving time for the slies but not mention about the recursion but um I'm going to actually clarify that actually recursion for kdg is not that bad but to achieve that performance uh that we need to do lots of work um on how to pipeline the proof okay so this talk the main target of this talk to explain how we can shrink the proing har to this stage and even further to about 10 seconds um but you will see that if we're using the background of the initial implementation
2022 it is implemented in Halo 2 and it needs about five minutes five full minutes in CPU to do uh this proof in one route so that means we we we somehow reduce that to 17 seconds each r um comparing to initially 300 or 400 seconds in CPU okay so what we so why this is possible and me the the problem is that why uh because if you look at um some other I I some other maybe um some other um fre benchmarks you will
see that usually the the GPU optimization for hello based maybe C evm is about five to six times right so how to actually increase this uh speeds up from five to six times to uh 50 times 30 times 50 times uh 50 times on the gas circuit and 30 times on the recursion circuit so how to achieve that um it's the main target of I'm going to explain in this Workshop so before I explain I'm going to just recap um the structure of the Plage circuit Okay so I because there are lots of protocols in kdg backand right log up loog up Shuffle permutation right okay so I'm going to
abstract the plun C just in with um three um abstractions the first abstraction is the the widness because the whole circuits is basically a large Matrix of witness and actually we will divide them further by the derivable weakness or the uh polinomial calculated weakness and the second part is the relations between the within cells so it's basically permutations and third thing is the with between uh columns right and we sometimes call these Gates call these perations okay and what we always do is so now before I talking about the the
breakdown of performance we we would like to study a example about the a very simple log up argument uh for example I have a and b and F columns and I would like to check A and B are within U6 right and you log up we so sometimes we have to do this right and and do a running sum of this and you can consider that if I put that into the derived Witness and then I have the committed witness uh but if I do not actually put that line as an explicit witness uh we have a degree increase in the final constraints right either you put
intermediate weakness that is derivable or you increase the polinomial degree of the the final constraints but there's one weakness that you cannot derive from uh just putting that into the final evaluation because this Mi is not polinomial derivable okay so that means we have to have an extra column sorry uh but what is the degree here like looks like two no um so what is degree here is that uh so of the constraint number four Oh you mean this one yes uh okay so so you cannot say this isal to one because you
have one over that you you sum that up you do not want to put intermediate which is here you have do um do I have you have to to multiply each right and sum them up so if you combine two of them then you actually multiply each one by this this this the degree will be two right so you have one more group the degrees goes up by one right depends on how many columns you have right but if you actually put this as explicit witness column then you do not have to put this down here so that mean you reduce degree by multiply the
denominator I'm am I am I okay that's May too much detail but which Pol degree we want to achieve here like so yeah or three four four four like uh so four four yeah so if if so okay so um it actually can so why we pick four there there are some kind of ser article behind that based on the CPU performance of MSM and GPU performance of H po so we need to pick a ratio so if we have some breakthrough on commitment then we can increase degree uh on the poly Evo if we do not have the
Breakthrough uh then four is currently our best um trial okay okay so so now we know that we did the the choice is that we we balance between the um the columns number of columns that we have to commit and the degree of the polinomial um there are some something else but basically we split them into um I I I I just support that everyone knows this uh and I suppose that uh we can have a formula um um the final Benchmark somehow the number of commitment that we have right
for each column but every time you increase intermediate derivable uh witness you plus one on the number of columns right because the commitment time for each column is somehow very stable and um then this is a time of the uh NT part and because you have to do on the Ted field you the the real um T that is sp is is this because if you T degree four then you plus two more degree two times times to um calculating the the vector The Entity vectors and this is the open time that you're going to um
spend but if we look at um the final proof of the uh spreading if we spreading the final proof Benchmark on one minut instructions on the CQ W you will see that uh it's our GP is basically 5.5 seconds um um on PO evaluation on De four right and you have um a few that's about 200 columns that you have to commit um before you doing qu validation and you have uh M opens about 7 700 milliseconds right so it's about 5 Seconds 5 seconds
and about less than 1 seconds okay but this is not case um on on CPU so this is The Benchmark breakdown on how it used to be um a CPU so in CPU po valuation takes about 300 seconds and commitment okay so so that actually um gives a problems about so you you cannot make a circuit that actually is fast in CPU and fast as well as in GPU because in CPU what we would like to do is that we somehow would like
to reduce the polinomial degree and then push everything as intermediate columns um on that uh um so let's let let's just skip this because these are also um derived or non-derivable uh witness okay so so in CPU what you would like to do is that you would have every polom derivable witness as a separate column right so that you can downgrade degree of qu valuation and then move that into um The Columns explicit columns and then commit that
okay but um in GPU what you're trying to do is that um GPU what trying to do is that uh instead of actually deda all the computations to MSM we would like to um make the polom very complex as complex as possible so that there is no intermediate winess um can be put into the the the witness Matrix so that means when we actually pick protocols we would like to pick protocols that has um polom derivable
Witnesses right so for example everyone tells that okay maybe log up is the maybe the best right because but log up has a problem that um Mi is not polinomial derivable right so so every time you have a nonp poom derivable witness uh you have to put extra and you're adding that to the commitment so when we actually com choose the combination about protocols we need to make sure that if this can be moved to the poly Evo without adding new commitments we should do that okay um but only moving this into po evaluation does not actually gives us 30
or 40 times of speeds because you see that um the ntity now takes about 9 Mond well this is only about 15 times quicker right this only takes about 15 times quicker so there there needs to be some fairly um breakdown of the micro benchmarks to actually somehow make this faster and we notice that um so not doing back Benchmark so there are some little secret um uh writing CA optimizations um so the first thing that we in the Cuda we
have um the caches and the cach m and the time cost of each operation right so sorry this is for the last thing okay um so now if we look into these three different Expressions the very common guess will be these two should be the same uh computation time while this should have extra computation time right that's the common sense because that's how um lots of people doing anti optimizing NT for
they think every time they have one one Stu or vector here it has to be the entity of the initial vectors okay but if you Benchmark enough um kernels you will find that it's completely not the case you will find that these two these two have exactly the same amount of time uh maybe five uh one or two milliseconds difference but this two this is um oh sorry I I should put this to be a d here B here so you put B here that this will be same um so the
conation that these two are same and this is slower than this and the reason that this one saw that is because it actually touched our memory miss here for the vector of e okay so now this gives the idea of put as many relevant vectors in one kernel as possible and how to do that um so that you have to make sure that your your GPU memory can hold all the memory M or cat all the all the vectors in in one place um
but it's impossible because every Vector you have on K22 is about 128 megabytes and the GPU only have 20 GB you can only catch about 60 so that means you you have to choice you have to choose what vectors you're going to catch so that every time you put a very super complicated valuation here you get the constant time of valuation and this is sorry um sorry okay so and this has a limit because once you put lots of vectors here and lots op here at a certain stage um the GPU somehow mees hit it um boundary so the th start to
increase okay so to do this um what we do is that we have to very carefully measure how much vectors we have we can cat on GPU right because we we would like to calculate in this then we will have to catch one two three four five six and plus two intermediate vectors actually holding the intermediate values right you have to take it very carefully about the intermediate values so that so to minimize intermediate um vectors that the GPU would like to cat we have to
always put a tree so that the right hand side only have Lens two that means you only need to actually have two Vector caches okay so now we have to move these two so we have to swap uh the left hand side with the right hand side and this actually makes huge difference if you if you do swap right because by swapping that you have one more cach then you can adding more Expressions here and you have have smaller number of groups when doing the evaluation so we have [Music] 1,300 um terms of degree two or four in the polar evaluation and if we can
somehow fit that into maybe one group that's a very small concept term but after we doing this we still have to filling that into about 20 groups okay so okay and you can do that manually um when you're coding that or you can do it automatically generate C kernels right but that's details okay okay so if we do that it is still not enough because if we do do some calculation on the numbers if we already know this observation then we still have two
choices one is that we do the entity all the vector entities before and every time we hit a cash hit a Miss we we loading them back into the GPU and this cost me about um 20 milliseconds to do a transfer right um and because we have um a few groups uh for example in our cases we have about um 25 groups and you doing this copy uh it will Tak you about close to 8 seconds right you're comparing to my previous um uh command line the whole point only takes about 2.5 seconds that
means um just like CPU if we just like CPU doing the entity for all the vectors and loading them on demand it didn't work didn't work because the memory copy the bandwidth will be the bottom net of this solution and to say that we still have the pre-calculation which is 1.8 um here right so if you doing the traditional way you have at least 10 seconds to do a poly evaluation for just the gate Expressions right if you look at the number here uh the gates should only take 2.3
seconds so that's the one and there are some other Gates that you canot actually put into um the the gates large Gates polinomial okay so how to somehow reduce this into uh what we have now is the second approach um the idea is very simple um we never do a NTT before we do the calculation every time in the GPU we find that we have do a deg for ntity we're doing that in GPU in a a synchronized way right because there are calculation latency and we still have some extra GPU
resource so we do use the left over GP resource to The Entity and this only cost about um 9 milliseconds doing the entity internal in internally in the GPU so this solution is has a problem is that um every time we have missing uh a hit missing on the vectors we have to do spend 9 milliseconds to do the entity right but the gain that comparing to 20 seconds we save 11 seconds here when we hit a missing and the majority of this the majority earning of this is
that we can cat more vectors because the non entity the vectors not in the coet form right is four times slower than the degree for coet um I mean extended field vectors so that means we have four times more space to cat vectors in GPU makes the group's number shrink by four right and then you get this which is exactly we get 2.5 um seconds of doing this and by repeating this um so that's that's the PO
valuation by repeating this um we can do that for look up and permutations right um if you can somehow shrink the number of mutations by rotation you get a little bit more earning but this somehow makes the uh 300 seconds in CPU into about 5 Seconds inp okay that's the uh optimization for the PO valuation um there another EV um optimization that we can do is at the beginning we say that um when doing commitments the this time cannot be saved because because um initially we need to do um this this GPU is um using
I think the fairly fast Ico Library so um but there's one more trick that you can save the time of this uh state of art Benchmark by just writing a GPU library for 64 bit MSM because when you're actually making a virtual machine that autoit is about 64 most of the winess is 64 so by implementing uh special Ms because we we are not experts on implementing msms we we design very Lexi method to actually implementing 64-bit MSM but it's still quicker than the state of art uh 252 bit MSM and it saves GPU memory as well so
by doing this we get another about 10% or 15% okay so that's for the G circuit um and now for the aggregator for the recursion um so because recursion is a large chunk of MSM circuits plus par circuits and the recursion has uses CRT to actually simulate the field which means the 64bit MSM does not work in recursion right so you have the the recursion the only thing that we can apply is the poly evaluation optimization okay and this is the uh
Benchmark after doing recursion optimization you see that we still get 30 30 times improve ination but not that much of MFL um okay and there one small little thing that actually makes um recursion slows because every time you generate weaknesses for the recursion circuits you have to do with this generation for msms and this cost me because now I'm trying to move everything to GPU this is this cost me about 2 seconds in a Lexi CPU a desktop i7 something um you switch to a powerful CPU this could be improved but
the whole point that we of this um working somehow we can delicate more stuff into GPU and have a very cheap CPU so this will cost about two seconds okay I currently I have no idea how to improve doing a synthesize in GPU but you will see that this actually occupies 40% comparing to the GP calculation in the recursion okay and there other thing that you can somehow reduce the damage that recursion costed on the proval it's because uh if we remember the big picture that every
time we do a recursion we only recur we doing a batching on the previous proof right if the recursion circuit is nice enough thetically we can hold two uh gas circuits right every two circuit slides we do a recursion that will actually uh reduce the damage of the recursion by a factor of two but we did not do that because um because we we would like to have something called uh host pre-compiled circuits so yes we can we can remove this out and plug in another guess here but um in our Solutions we actually plug in a host precompiler here um okay so
now why why we need to do that um it's because sometimes there are circuits like um signatures ecdsa that we need um it's very Lexing when you return that into web assembly code even web assembly is 64bit but it's still slow okay so the idea of um encoding host API in web assembly is that we we we Define the host API here without actually inforce any constraints on that and this will actually compile to S now we have W to shoot the compiling so we have this
and in the host in the gas circuit when we actually have close operations we we're just filling all the witness here um and without proving anything about the constraint of the witness and we have another whole circuit that actually um enforce the input and output by the semantics of operation and in the batch oh sorry there there's something underneath out of the screen u in the batch um the bat circuit actually comparing um the column of this the commitment of the column of this with the commitment of the column on the
whole circuits so that the they can just connect it um if like you can write in the whole circus uh using gkr and using zero of somehow comparing the multi commitment with univers commitment so that giv me a little bit uh flexibility but at the cost of we can only doing recursion for one slice proof right because we're doing some uh if we actually adding host proofs here we don't have enough roles in the recursion circuit okay uh if anyone interested in uh connect connecting gkr with kdg then
there's a do here but that's not the um C Target okay now we have the speed optimization right so this gives me about 16 to 17 seconds for one minut instructions and it seems that I have touched the boundary I cannot do even further but what we can do is that we I can I can shrink the the trace I mean so the the the the story that most of the ckvm somehow choose to use a 62 bit um simple instruction set
because uh you do not need to handle lots of gates which actually improve the speed but the problem that you just imagine that you have a u22 arithmatic in defi system that it usually takes about more than 50 instructions to do a u 128 in defy right and in web assembly it's still taking about 30 to 40 instructions but that's a saving of half right but actually um we can save that by removing stuffs like stack operation just imagine that um in a register based in a register based VM right every
time you have to you do an operation you load something from memory and put out that into the register and you do the operation and then St it back if the register actually stores intermediate result then you do not can you can save that store right can save that store um but in the step but because register still um part you still have to actually store the rest back when doing functions CA Contex whiches so so in a stack based VM what we can do is that if we looking at this Trace we will find that there are complicated instruction like this or you
can replace this by I64 any complicated instructions uh here you can replace any complicated instructions in this graph with this I add and you will find that there are two wasted instructions um at this point and this point these two points are just specify the stack pointers that your instructions has to apply right but that's actually a web assembly feature so you specify the stack position and load that onto the top of stack and then you do the operation so if we want like to actually simplify the
trace we can remove move these two instructions into the Circuit of the ad that will actually save you in this case about 60% of the instructions and in overall programming usually say about 45% of the traits of the web assembly okay so and this only increase a little bit about the PO evaluation part but it has nothing to do with the commitment the part because the columns number of columns fixed right so by actually L emit this and move that into this instructions uh our measurement
that only gets 3% performance penalty but you get super smaller TR right um You can you have a try and turn C was like Trace optimization on for uh implementing uh a curve in web assembly you'll find that it safe to about 40% of the SP and if you're comparing that one with maybe 32 bit it saves more especially it saves uh memory copy if writing lots of uh rust code there lots of memory copy and it Sayes memory copy um bitwise stuff and saes this step but if you're comparing to register base VM
then this will be uh register loading and store but actually the you know res base BM they do not get as much damage as web assembly because some of the intermediate sorry some of the intermediate uh result can stay in the register without storing back but in web assembly this is the uh fact okay so yeah that's basically uh what I'm trying to um talk today and at the end I would like to quote uh Hardware outlooking that can be done to further improving a VM and this
is the something that I um read from then fpga Benchmark but let keep it simple uh we can get polinomial back to uh less than 2 seconds if we have uh as about um not that maybe 28 million so we will do this we get about 2 seconds poly evaluation but the problem that once you touch that boundary um you only get 3 seconds improvements right it's not not big deal to actually make acid at moment um but actually the acid can improve the poly
valuation by another fact of 50 more than 50% okay thanks that's that's my talk if you have any questions you can ask yeah what's that Benchmark where does it come from is it the same Benchmark uh the same Benchmark you just replace that with fpj okay yeah that they have a fpj library so but how do you know is the same because you run this on some input you generate uh sorry what's the input for this benchmark how do you know it's the same input for uh they they run this Benchmark on their fpj machine so we have uh cooperation with them to test
that out yeah um and but this is an estimation so there are some this the the benchmark test here so that's saying that they ttic and they presumably if you do a you get increasing H and something else uh I I think we can publish this uh this send that to me with no uh any secret so we can have a look at this um but the problem is that if we do an ethic to just increase 3 seconds maybe it's not worth that uh you have to
maybe if you can adding MSM to the fpj then you get huge M but currently 64bit special MSM is works fine because I think every time you get a 64bit ckvm ring 10 seconds or 15 seconds is at at moment should be fine for most of scenarios um but I mean the potential is still there you we have powerful Hardware designed for B 2506 po valuation I have a couple questions okay okay no well first off the gas GR idea about using the multi set hash for
improving the memory Integrity yeah using um improve performance that's so because we have a simpler model because the multi has is using a hash that you can commute right okay so what we do is that we very close because we not actually doing hash we're comparing the commit yeah so we gain a little bit um if you're doing multi set hash but because we have to compute the commitment doing the proof generation R anyway so this is a byproduct in our use case but the
shortage of our solution is that because we have two columns of the memory that's K = 22 so that's only 64 megabyte memory you cannot you cannot make bigger memory because we're using commitment pols so we compare the commitment between the uh slices to actually ensure the memory are continuous and this saves the H this saves the harush but introduce a memory boundary yep just a generic question for you one of the powers of was is that we can use these on mobile devices which have uh
very different architecture for the GPU processing that there's not going to be much penalties from memory for swapping out the different caches may I so to be honest I did not see any customers using that in so people using that just because they have a browser application written in type script they putting into assembly script so so if people using rust they maybe intend to using there lots of very fancy vmd like Risk Z but you people not bothering writing rust um then web assembly in your browser will be a choice right but if you're doing a defi
um we we we providing solutions for some um defy systems if you're doing defi then you get quite a few benefits by having 64bit and shrink Trace so U 128 Defy arithmatic is a trace killer for C bit uh I don't know what to call this but um reducing risk in making it changing the app codes from the trace information yeah is there um have you found a trade off between reducing your your Trace in instructions between that and also
yeah sure um so so there's there's a you're looking at the breakdown of The Benchmark uh okay so because I'm doing a doing a VM right um all the stacks registers memories everything that you have even you have smaller set of instruction the the you cannot shrink the columns that you have to commitment very a lot right so in a GPU lot like CP in CPU you get lots of gain by using simple instructions in GPU if
we shrink our instruction set from 140 to maybe like Risk five like 30 or 40 right you get maybe 50% so you get get that shrink by three seconds 3 seconds out of 12 is not very attractive to to us because you're given because so there there are some instructions that cannot be very easily implemented in 32 bit for example uh u64 signed reminder right um but
ionically this instruction is not used for applications very often yeah but to 2.7 seconds in GPU is I think it's fine uh it gives fully competitive with web assembling browser okay I also just have one last generic question about um like you said the uh a lot of circuits are getting to the point of metal at this point so you can't optimize that much yeah so but at the same time the recursion recursive proof yeah do you see more work being done to optimize those in the future um so you're you're asking whether there will be further optimization on the recursion
side I hope so because I think some other VM can do recursion in GPU in GPU in 1 seconds I totally admire how they achiev that we we have 3.5 seconds plus some synthesiz um cost I think because this is kdg proof right if we can somehow using fancy folding to actually doing the recursion maybe we get some improvement um or because we we are small group I I I cannot afford actually dive into other recursion at the moment
it's but I hope maybe after a while uh we get some better MSM synthesized to actually wipe out two seconds on the synthesiz yeah oh on that too secondary you mentioned that and the synthesis might it's actually performs better in your CPU yeah yeah so yeah you see that so you see the GPU case I I want to have because we have a um approving thing uh in Cloud uh we would like to actually shrink the demount of CPU usage as much as possible so that sorry so that I can using one CPU not that good not epy CPU but a simple CPU to actually have eight
gpus so but if we focus on doing that the synthesizing of the recursion will be 2 seconds at the moment it depends on how much I can afford to pay to increase the CPU um standard I think these days you get CPU epy iing n something it's twice or maybe 1.5 more expensive than GPU so so yeah it's so so if you can tolerate the two seconds of synthesize then that's fine not many applications are very strict on um the the final Bing speed but yes I know someone uh some VM
has recursion for each slice that can be diluted into to 1 seconds um that will be a huge benefit for them to have that but our botton net uh I find at moment is the recursion right even you somehow shrink the traces improve speed of guests it only gives you 10 to 20 but recursion will be a majority Target that I I should focus okay okay okay thanks thanks for coming thank thank you