Можно ли делать вставки MSIL в код на c# ?
От: SergeyY  
Дата: 03.11.16 09:14
Оценка:
Можно ли делать вставки 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 регистр

}

Заранее, большое спасибо.
Отредактировано 04.11.2016 22:07 VladD2 . Предыдущая версия .
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.