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

RyuJIT should be able to discover and emit bool-to-int conversions in the most efficient way. #4399

Closed
redknightlois opened this issue Jul 29, 2015 · 2 comments
Labels
area-CodeGen-coreclr CLR JIT compiler in src/coreclr/src/jit and related components such as SuperPMI enhancement Product code improvement that does NOT require public API changes/additions optimization tenet-performance Performance related issue
Milestone

Comments

@redknightlois
Copy link

Usual ways to convert boolean into integers in C# are:

  • If true then 1 else 0
  • Convert.ToInt32(bool)
  • Unsafe bool in the stacks tricks.

While the latest is the most efficient, it is a pain to use. The other two which are used in plenty places including the Framework itself could emit a very efficient assembly code instead of the standard method call (as of right now).

Differences in performance are huge:

// BenchmarkDotNet=v0.7.6.0
// OS=Microsoft Windows NT 6.2.9200.0
// Processor=Intel(R) Core(TM) i5-2500K CPU @ 3.30GHz, ProcessorCount=4
// CLR=MS.NET 4.0.30319.42000, Arch=64-bit [RyuJIT]
Common: Type=Jit_BoolToInt Mode=Throughput Platform=X64 .NET=Current

Method Jit AvrTime StdDev op/s
Framework LegacyJit 1.16 us 28.20 ns 858517.79
IfThenElse LegacyJit 1.08 us 44.58 ns 929458.93
UnsafeConvert LegacyJit 595.83 ns 5.79 ns 1678333.61
Framework RyuJit 1.31 us 18.64 ns 765539.56
IfThenElse RyuJit 1.31 us 16.05 ns 761023.73
UnsafeConvert RyuJit 896.80 ns 6.27 ns 1115078.04

Repro: https://gist.github.com/redknightlois/c1ae5ddc6f73c2e53c9b

category:cq
theme:optimization
skill-level:intermediate
cost:small

@msftgits msftgits transferred this issue from dotnet/coreclr Jan 30, 2020
@msftgits msftgits added this to the Future milestone Jan 30, 2020
@BruceForstall BruceForstall added the JitUntriaged CLR JIT issues needing additional triage label Oct 28, 2020
@BruceForstall
Copy link
Member

BruceForstall commented Nov 20, 2020

You could do the "unsafe" way even faster (and safer; the repro case looks illegal to me):

        public int UnsafeConvert2()
        {
            int sum = 0;
            byte[] ab = Unsafe.As<byte[]>(bits);
            for (int i = 0; i < N; i++)
            {
                sum += ab[i];
            }
            return sum;
        }
Method Mean Error StdDev Code Size
Framework 1,181.6 ns 3.20 ns 2.99 ns 70 B
IfThenElse 1,192.6 ns 12.21 ns 10.82 ns 67 B
UnsafeConvert 607.3 ns 3.84 ns 3.59 ns 74 B
UnsafeConvert2 419.9 ns 1.47 ns 1.23 ns 54 B

The problem is this is unsafe because the spec says:

III.1.1.2 Boolean data type
A CLI Boolean type occupies 1 byte in memory. A bit pattern of all zeroes denotes a value of
false. A bit pattern with any one or more bits set (analogous to a non-zero integer) denotes a
value of true. For the purpose of stack operations boolean values are treated as unsigned 1-byte
integers (§III.1.1.1).

There may be processor-specific implementations that could generate better code for the first two cases (which are equivalent, actually). Given that this optimization is very specific, and requires a specific pattern, unless there is a real scenario where this is important, it's unlikely to be implemented. Thus, I'm going to close this.

@BruceForstall BruceForstall removed the JitUntriaged CLR JIT issues needing additional triage label Nov 20, 2020
@BruceForstall
Copy link
Member

@ghost ghost locked as resolved and limited conversation to collaborators Jan 5, 2021
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
area-CodeGen-coreclr CLR JIT compiler in src/coreclr/src/jit and related components such as SuperPMI enhancement Product code improvement that does NOT require public API changes/additions optimization tenet-performance Performance related issue
Projects
None yet
Development

No branches or pull requests

3 participants