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

New version of execution_result #219

Merged
merged 1 commit into from
Jul 16, 2020
Merged

New version of execution_result #219

merged 1 commit into from
Jul 16, 2020

Conversation

axic
Copy link
Member

@axic axic commented Feb 28, 2020

This re-implements the execution_result struct. Now it has three valid
states: value, void and trap. The struct is simplified, close to POD
type, std::vector is not used any more.

In benchmarks for certain cases (such as ecpairing) deleting an std::vector took quite a big chunk of time. I thought perhaps the moved stack for the return value could be the culprit, hence did this change. However my local benchmarks are inconclusive.

@chfast
Copy link
Collaborator

chfast commented Feb 28, 2020

Benchmarking before cepairing landing does not make sense then.

@axic
Copy link
Member Author

axic commented Feb 28, 2020

Benchmarking before cepairing landing does not make sense then.

Hm? It is in the bench-ecpairing branch.

@axic axic force-pushed the execute-return branch 2 times, most recently from 49d3278 to 401c213 Compare April 24, 2020 11:08
@axic
Copy link
Member Author

axic commented Apr 24, 2020

Rebased so we can run another set of benchmark comparison post 0.1.0.

lib/fizzy/execute.cpp Outdated Show resolved Hide resolved
@codecov
Copy link

codecov bot commented Apr 24, 2020

Codecov Report

Merging #219 into master will increase coverage by 0.11%.
The diff coverage is 94.33%.

@@            Coverage Diff             @@
##           master     #219      +/-   ##
==========================================
+ Coverage   99.17%   99.28%   +0.11%     
==========================================
  Files          49       49              
  Lines       13237    13227      -10     
==========================================
+ Hits        13128    13133       +5     
+ Misses        109       94      -15     

@axic
Copy link
Member Author

axic commented Jun 1, 2020

I think this can be revived in a simplified way (e.g. only affected "public api") once the span changes are pushed.

Copy link
Collaborator

@chfast chfast left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There is a problem with struct layout of bool + std::optional<uint64_t>. In whatever order you put these the end struct size will be 24 bytes. Therefore it cannot be returned by registers from a function.

We should not use std::optional<uint64_t>, just make flat struct as

struct execution_result
{
    bool trapped;
    bool has_value;
    uint64_t value;
};

https://godbolt.org/z/m3GQsE

@axic
Copy link
Member Author

axic commented Jun 9, 2020

struct execution_result
{
    bool trapped;
    bool has_value;
    uint64_t value;
};

Would an enum make sense?

enum class execution_status
{
   Trapped,
   WithResult,
   WithoutResult,
}
struct execution_result
{
    execution_status status;
    uint64_t value;
};

@chfast
Copy link
Collaborator

chfast commented Jun 9, 2020

Would an enum make sense?

Yes, performance wise this should be the same.

Although, you will probably need additional helpers like result.trapped() and make the enum "private".

@chfast
Copy link
Collaborator

chfast commented Jun 9, 2020

Also there is Result in WasmEngine, so unify them.

    struct Result
    {
        bool trapped = false;
        std::optional<uint64_t> value;
    };

@axic axic force-pushed the execute-return branch 3 times, most recently from f87078e to ae85c67 Compare June 30, 2020 09:37
@chfast chfast force-pushed the execute-return branch 3 times, most recently from 7401072 to f7ac7d1 Compare July 14, 2020 12:20
pass();
else
fail("Unexpected returned value.");
continue;
}

if (result->stack.size() != 1)
if (!result->has_value)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

wrong.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Bummer, actually should have removed this part of the code with #398.

lib/fizzy/execute.hpp Outdated Show resolved Hide resolved
@chfast
Copy link
Collaborator

chfast commented Jul 15, 2020

Benchmarks without "Simplify trap handling".
GCC10, Haswell 4.0 GHz

Comparing master to execres
Benchmark                                                            Time             CPU      Time Old      Time New       CPU Old       CPU New
-------------------------------------------------------------------------------------------------------------------------------------------------
fizzy/execute/blake2b/512_bytes_rounds_1_mean                     -0.1125         -0.1125            87            77            87            77
fizzy/execute/blake2b/512_bytes_rounds_16_mean                    -0.1232         -0.1232          1307          1146          1307          1146
fizzy/execute/ecpairing/onepoint_mean                             -0.1092         -0.1092        435697        388114        435698        388117
fizzy/execute/keccak256/512_bytes_rounds_1_mean                   -0.0827         -0.0827           104            95           104            95
fizzy/execute/keccak256/512_bytes_rounds_16_mean                  -0.0838         -0.0838          1516          1388          1516          1389
fizzy/execute/memset/256_bytes_mean                               -0.1183         -0.1183             7             6             7             6
fizzy/execute/memset/60000_bytes_mean                             -0.1095         -0.1095          1564          1393          1564          1393
fizzy/execute/mul256_opt0/input0_mean                             -0.0695         -0.0695            27            25            27            25
fizzy/execute/mul256_opt0/input1_mean                             -0.0685         -0.0685            27            25            27            25
fizzy/execute/sha1/512_bytes_rounds_1_mean                        -0.0862         -0.0862            93            85            93            85
fizzy/execute/sha1/512_bytes_rounds_16_mean                       -0.0845         -0.0845          1288          1179          1288          1179
fizzy/execute/sha256/512_bytes_rounds_1_mean                      -0.0915         -0.0915            95            86            95            86
fizzy/execute/sha256/512_bytes_rounds_16_mean                     -0.0872         -0.0872          1299          1186          1299          1186
fizzy/execute/micro/eli_interpreter/halt_mean                     -0.2347         -0.2347             0             0             0             0
fizzy/execute/micro/eli_interpreter/exec105_mean                  -0.1350         -0.1350             5             4             5             4
fizzy/execute/micro/factorial/10_mean                             -0.2747         -0.2747             1             0             1             0
fizzy/execute/micro/factorial/20_mean                             -0.2645         -0.2645             1             1             1             1
fizzy/execute/micro/fibonacci/24_mean                             -0.2688         -0.2688          9929          7260          9929          7260
fizzy/execute/micro/host_adler32/1_mean                           -0.3320         -0.3320             0             0             0             0
fizzy/execute/micro/host_adler32/100_mean                         -0.3484         -0.3484             5             3             5             3
fizzy/execute/micro/host_adler32/1000_mean                        -0.3510         -0.3510            45            29            45            29
fizzy/execute/micro/spinner/1_mean                                -0.0660         -0.0663             0             0             0             0
fizzy/execute/micro/spinner/1000_mean                             -0.1597         -0.1597            10             9            10             9

The "Simplify trap handling" does not change the results.

@chfast chfast force-pushed the execute-return branch 2 times, most recently from b9b0245 to 6a4386e Compare July 15, 2020 20:41
@@ -18,7 +18,7 @@ uint64_t call_table_func(Instance& instance, size_t idx)
{
const auto& elem = (*instance.table)[idx];
const auto res = elem->function(instance, {}, 0);
// ASSERT_TRUE(res.result.has_value());
assert(res.has_value);
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why not keeping ASSERT_TRUE? (I'm not sure why it was disabled in this PR in the first.)

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Apparently the ASSERT_TRUE only works inside TEST as it use return for early exit.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Changed to EXPECT_TRUE.

@chfast chfast force-pushed the execute-return branch 3 times, most recently from aa8eca4 to 5fce948 Compare July 16, 2020 06:48
@chfast chfast changed the title Change the return value of execute() from std::vector to std::optional New version of execution_result Jul 16, 2020
@chfast chfast marked this pull request as ready for review July 16, 2020 07:53
auto host_foo2 = [](Instance&, span<const uint64_t>, int) -> execution_result {
return {true, {}};
};
auto host_foo1 = [](Instance&, span<const uint64_t>, int) -> execution_result { return Void; };
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These are not executed, but foo1 import returns a result (foo2 is void)

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

But both were also traps in the same time. You cannot have trap + value now.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Before: both were trapping, but foo1 supposed to return a result and foo2 not
After: foo1 does not trap and returns nothing, foo2 traps

@gumb0 is this the correct intended behaviour?

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The implementation doesn't matter, I would just make them both trap.

@axic
Copy link
Member Author

axic commented Jul 16, 2020

Looks good to merge apart form that single question.

And the header with trapped_tag, etc. does not particularly looks nice, but okay if it can't be made nicer.

constexpr execution_result(uint64_t _value) noexcept : has_value{true}, value{_value} {}

constexpr explicit execution_result(trapped_tag) noexcept : trapped{true} {}
constexpr explicit execution_result(bool success) noexcept : trapped{!success} {}
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This constructor should not be used by users. We can also add default value bool success = true to allow {} as previously. But rather single way of doing things in internal code is better.

This re-implements the execution_result struct. Now it has three valid
states: value, void and trap. The struct is simplified, close to POD
type, std::vector is not used any more.

Co-authored-by: Paweł Bylica <chfast@gmail.com>
@chfast chfast merged commit 174ad31 into master Jul 16, 2020
@chfast chfast deleted the execute-return branch July 16, 2020 15:35
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants