Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Number often uses to_u1024_bytes for bitwise/arithmetic operations, but u1024 has 128bytes while Number is up to 1024bytes #88

Closed
6293 opened this issue Jun 28, 2023 · 16 comments
Labels
breaking Breaking API changes epic Epic task question Further information is requested
Milestone

Comments

@6293 6293 changed the title BitwiseOp uses to_u1024_bytes, but the input could be r2048/r4096/r8192 BitwiseOp uses to_u1024_bytes on Number, but u1024 has 128bytes while Number is at most 1024bytes Jun 28, 2023
@6293 6293 changed the title BitwiseOp uses to_u1024_bytes on Number, but u1024 has 128bytes while Number is at most 1024bytes Number often uses to_u1024_bytes for bitwise/arithmetic operations, but u1024 has 128bytes while Number is at most 1024bytes Jun 28, 2023
@6293 6293 changed the title Number often uses to_u1024_bytes for bitwise/arithmetic operations, but u1024 has 128bytes while Number is at most 1024bytes Number often uses to_u1024_bytes for bitwise/arithmetic operations, but u1024 has 128bytes while Number is up to 1024bytes Jun 28, 2023
@6293
Copy link
Contributor Author

6293 commented Jun 28, 2023

e.g. Shl/Shr is also applicable to r2048 reg

@dr-orlovsky
Copy link
Member

It is true, but it is just a sideffect. The only solution to this is to have a different Number types for A and R registers. There is no point in SHL/SHR and other arithmetic operations for R register since they are used to represent hashes/curve points and can't be operated with normal arithmetics.

@6293
Copy link
Contributor Author

6293 commented Jun 28, 2023

There is no point in SHL/SHR and other arithmetic operations for R register

Unlike bitwise operations like SHL/SHR, arithmetic operation does not exist for R register. Instead of introducing another Number type for R-reg, can we stop using Number on bitwise operations for R-reg?

@6293
Copy link
Contributor Author

6293 commented Jun 28, 2023

because it is relatively easier to perform bitwise operations on a byte array, than arithmetic operations

@dr-orlovsky
Copy link
Member

I think this is a very good idea!

@dr-orlovsky dr-orlovsky added this to the 0.10.4 milestone Jun 29, 2023
@dr-orlovsky dr-orlovsky removed this from the 0.10.4 milestone Jul 9, 2023
@dr-orlovsky
Copy link
Member

The change is quite complex: it requires changing multiple APIs which abstract a specific register type and allow to operate with any A, R or F register providing Number/MaybeNumber.

The change is also an API-breaking

@dr-orlovsky dr-orlovsky added question Further information is requested epic Epic task breaking Breaking API changes labels Jul 9, 2023
@6293
Copy link
Contributor Author

6293 commented Jul 13, 2023

We we need to do is to change CoreRegs::get so that it accepts impl Into<RegAF> instead of impl Into<RegAFR>. When one wants to get R-reg value, they should use CoreRegs::get_r instead

@dr-orlovsky
Copy link
Member

dr-orlovsky commented Jul 13, 2023

Agree, that is the best way forward. Can you work on that please?

@6293
Copy link
Contributor Author

6293 commented Jul 13, 2023

Do we stop using MaybeNumber on PutOp::PutR and introduce something like ByteArray? In this scenario, Number is now nothing to do with R-reg, so maybe Number should internally be [u8; 128] instead of [u8; 1024]. This is a breaking change, but no changes to bytecode.

@dr-orlovsky
Copy link
Member

It's ok to have API breaking changes - the bytecode breakes (or business logic in instruction execution) is much much worse.

I think your proposal is a good solution.

@6293
Copy link
Contributor Author

6293 commented Jul 21, 2023

Hi, hasn't been active for a while. I am facing a challenge regarding with the solution above. Taking MoveOp::MovR for example:

MoveOp::MovR(reg, idx1, idx2) => {
    regs.get_r_mut(*reg, idx2).copy_from_slice(regs.get_r(*reg, idx1));
}

This will not compile because it borrows regs as immutable while also borrowing as mutable. We cannot indicate on a method signature that only a subset of the struct is borrowed. One way to solve this problem is that just expose registers across crate. Alternatively we can have similar getter/setter as RegAF registers, which creates a copy of register value instead of returning reference. With this approach, however, I am afraid that copying of large array occurs too often.

@dr-orlovsky
Copy link
Member

I think we just need to clone the result of regs.get_r here - that will be much simplier. Not perfect, but it will make refactoring reasonably-sized.

@6293
Copy link
Contributor Author

6293 commented Jul 21, 2023

A heap allocation is inevitable when cloning a slice. I thought we should ensure that a program would run without any memory allocation except at VM startup time, are we ok with that?

@dr-orlovsky
Copy link
Member

dr-orlovsky commented Jul 21, 2023

The point was to avoid large memory allocations which may affect low-end hardware (like 64kB+ etc).

Even now AluVM does a lot of allocations of a smaller size.

@dr-orlovsky
Copy link
Member

I mean it would be great to avoid any allocations runtime, but I think this is the larger goal than the scope of this issue and it will require more refactoring, so should be left for the future.

@dr-orlovsky dr-orlovsky added this to the v0.12.0 milestone Feb 26, 2024
@dr-orlovsky
Copy link
Member

Fulfilled with v0.12

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
breaking Breaking API changes epic Epic task question Further information is requested
Projects
None yet
Development

No branches or pull requests

2 participants