Можно ли делать вставки MSIL в код на c# ? По аналогии, как в C++ можно сделать ассемблерную вставку в код.
Возник такой вопрос, потому что, программа написанная на C#
не использует полные арифметические возможности процессора.
У меня программа, будет работать с длинными целыми.
Будет тип,
struct UInt128
{
UInt64 high;
UInt64 low;
}
Чтобы определить операции умножения и деления двух экземпляров UInt128, очевидно, придется перемножить (или разделить) пары UInt64 внутри этого типа,
затем складывать промежуточные результаты, и в итоге, записывать верхнюю и нижнюю UInt64-части, внутри типа UInt128.
К примеру, для умножения, имеем,
UInt128 a;
UInt128 b;
Первый промежуточный результат — перемножим два UInt64-типа,
a.low * b.low. В итоге, получим результат — 128-битное число, в виде двух 64-битных чисел.
Процессор позволяет это сделать одной
ассемблерной инструкцией mul — результат, в регистрах
RDX:RAX, причем в RDX — старшие 64 бита, а в RAX — младшие 64 бита.
И вот, в этот момент, нет возможности (или по крайней мере, мне неизвестно как) средствами c# прямо и получить эту старшую часть — которая
уже содержится в регистре RDX !
(только часть RAX и будет в результате получена — в произведении, которое тоже имеет тип UInt64).
Чтобы получить старшую часть — нужно при перемножении двух UInt64 — их в свою очередь, разбивать
на два под-типа UInt32, и
делать 4 умножения вместо одного, на уровне процессора.
От этого ниже производительность (а в некоторых задачах, в том числе моей, эти
умножения-деления будут занимать весьма весомую часть), и не используются все возможности 64-битных процессоров.
(Аналогичная возможность и при делении, процессор позволяет разделить 128-битное содержимое RDX:RAX на 64-битное содержимое, к примеру RBX регистра, в то время,
как в C# можно делить только 64-битные числа, на 64-битные числа. Но пока — вопрос
как хотя бы только умножение реализовать. Если это можно, то далее с MSIL вставками
можно и деление оптимизировать)
На c++ можно было бы просто сделать ассемблерную вставку, и в нужный момент, прочитать-таки, этот регистр RDX, после умножения, и не делать в программе
в 4 раза больше операций умножения, чем это необходимо на процессорном уровне.
Можно ли подобное сделать, с помощью вставки MSIL в код на C# ? Т.е. заставить после умножения сгенерировать такой машинный код, который прочитает регистр RDX
и запишет его в UInt64 переменную, и не надо было бы делать лишних умножений?
UInt64 a;
UInt64 b;
UInt128 result;
result.Low = (UInt64)(a * b);
{в этот момент в регистре RDX уже содержится старшие 64 бита, часть умножения (a * b). Нужно чтобы MSIL сгенерировал для 64-битных процессоров, аналогичный
result.High = RDX регистр
}
Заранее, большое спасибо.