C#将bool重新解释为字节/整数(无分支) [英] C# reinterpret bool as byte/int (branch-free)
问题描述
在C#中是否有可能将 bool
转换为 byte
或 int
(或者实际上是任何整数类型)没有分支?
Is it possible in C# to turn a bool
into a byte
or int
(or any integral type, really) without branching?
换句话说,这不是 足够好:
In other words, this is not good enough:
var myInt = myBool ? 1 : 0;
我们可能会说我们想重新解释 bool
作为基础 byte
,最好使用尽可能少的指令。目的是避免分支预测失败,如此处。
We might say we want to reinterpret a bool
as the underlying byte
, preferably in as few instructions as possible. The purpose is to avoid branch prediction fails as seen here.
推荐答案
也许可行吗? (想法来源)
using System;
using System.Reflection.Emit;
namespace ConsoleApp10
{
class Program
{
static Func<bool, int> BoolToInt;
static Func<bool, byte> BoolToByte;
static void Main(string[] args)
{
InitIL();
Console.WriteLine(BoolToInt(true));
Console.WriteLine(BoolToInt(false));
Console.WriteLine(BoolToByte(true));
Console.WriteLine(BoolToByte(false));
Console.ReadLine();
}
static void InitIL()
{
var methodBoolToInt = new DynamicMethod("BoolToInt", typeof(int), new Type[] { typeof(bool) });
var ilBoolToInt = methodBoolToInt.GetILGenerator();
ilBoolToInt.Emit(OpCodes.Ldarg_0);
ilBoolToInt.Emit(OpCodes.Ldc_I4_0); //these 2 lines
ilBoolToInt.Emit(OpCodes.Cgt_Un); //might not be needed
ilBoolToInt.Emit(OpCodes.Ret);
BoolToInt = (Func<bool, int>)methodBoolToInt.CreateDelegate(typeof(Func<bool, int>));
var methodBoolToByte = new DynamicMethod("BoolToByte", typeof(byte), new Type[] { typeof(bool) });
var ilBoolToByte = methodBoolToByte.GetILGenerator();
ilBoolToByte.Emit(OpCodes.Ldarg_0);
ilBoolToByte.Emit(OpCodes.Ldc_I4_0); //these 2 lines
ilBoolToByte.Emit(OpCodes.Cgt_Un); //might not be needed
ilBoolToByte.Emit(OpCodes.Ret);
BoolToByte = (Func<bool, byte>)methodBoolToByte.CreateDelegate(typeof(Func<bool, byte>));
}
}
}
基于每次发射的Microsoft文档。
based on microsoft documentation of each emit.
- 将参数加载到内存(布尔值)中
- 加载到内存int = 0的值
- 比较是否有任何参数大于该值(可能在此处分支?)
- 如果为true,则返回1 0
- load the parameter in memory (the boolean)
- load in memory a value of int = 0
- compare if any the parameter is greater than the value (branching here maybe?)
- return 1 if true else 0
第2行和第3行可以删除,但是返回值可以不是0/1
line 2 and 3 can be removed but the return value could be something else than 0 / 1
就像我在开始时所说的,该代码是从另一个响应中获取的,这似乎是可以的,但在进行基准测试时似乎很慢,查找 .net DynamicMethod慢
找到使它更快的方法
like i said in the beginning this code is taken from another response, this seem to be working yes but it seem slow while being benchmarking, lookup .net DynamicMethod slow
to find way to make it "faster"
您可以使用。boolean中的GetHashCode ?
true将返回1的int和false 0
true will return int of 1 and false 0
然后可以 var myByte =(byte)bool.GetHashCode()
;
you can then var myByte = (byte)bool.GetHashCode()
;
这篇关于C#将bool重新解释为字节/整数(无分支)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!