Справочник функций

Ваш аккаунт

Войти через: 
Забыли пароль?
Регистрация
Информацию о новых материалах можно получать и без регистрации:

Почтовая рассылка

Подписчиков: -1
Последний выпуск: 19.06.2015

"Лишнее" в сборках CLR:Pure MC++

842
08 января 2010 года
sigmov
301 / / 16.09.2008
Использую VS2008.

Меня некоторое время назад заинтересовал вопрос, почему же сборки сделанные на C# или MC++(CLR:Safe) имеют размер 8кб. А вот сборки сделанные на MC++(CLR:Pure) с тем же кодом имеют размер 24 и более кб.

Вообщем открыл я сборку CLR:Pure ildasm'ом и увидел так кучу всякого кода для взаимодействия царств Native и Clr:

 
Код:
.field static assembly valuetype '<CppImplementationDetails>'.$ArrayType$$$BY00Q6MPBXXZ modopt([mscorlib]System.Runtime.CompilerServices.IsConst) '?A0x250abb45.__xc_mp_z' at D_000030EC
.field static assembly int32 '?Uninitialized@CurrentDomain@<CrtImplementationDetails>@@$$Q2HA'
.custom instance void [mscorlib]System.Runtime.CompilerServices.FixedAddressValueTypeAttribute::.ctor() = ( 01 00 00 00 )
.field static assembly method void *() '?A0x250abb45.?Uninitialized$initializer$@CurrentDomain@<CrtImplementationDetails>@@$$Q2P6MXXZA' at D_000030CC
.field static assembly valuetype '<CppImplementationDetails>'.$ArrayType$$$BY00Q6MPBXXZ modopt([mscorlib]System.Runtime.CompilerServices.IsConst) '?A0x250abb45.__xi_vt_a'/
..................


И рад был бы. Но "C" и "С++" не используется в моем проекте на MC++ в принципе(поэтому надобности в подобном захламлении сборки не вижу). Однако возможность использовать указатели тем не менее очень нужна.

Попытался "исправить" положение. Весь проект составил из одного *.cpp файла и в самом верху(первой же строкой) продекларировал:
#pragma managed

И ничего. Хоть вешайся. Захламления сборки ненужным кодом это не убрало....

Может кто подскажет как это сделать....:confused:

А то руки уже к паре ildasm\ilasm тянуться:(
5
09 января 2010 года
hardcase
4.5K / / 09.08.2005
Сдается мне код инфраструктуры MC++ нельзя ликвидировать, ну разве что посредством декомпилятора.

Цитата: sigmov
"C" и "С++" не используется в моем проекте на MC++ в принципе(поэтому надобности в подобном захламлении сборки не вижу). Однако возможность использовать указатели тем не менее очень нужна.

А чем C# в таком случае не угодил?

842
10 января 2010 года
sigmov
301 / / 16.09.2008
Цитата: hardcase
А чем C# в таком случае не угодил?



Указатели!!!

В C# указатель можно объявить только на Value Type, не являющийся Generic'ом и не содержащий в себе ссылочных типов.

В MC++ архитектура pin_ptr<G> свободно с этим справляется.

5
10 января 2010 года
hardcase
4.5K / / 09.08.2005
Цитата: sigmov
Указатели!!!

В C# указатель можно объявить только на Value Type, не являющийся Generic'ом и не содержащий в себе ссылочных типов.


Вполне разумно. Зачем создавать указатель на ссылочный тип? ;) Но с генериками да, вышел косячокс, впрочим есть замечательный тип GCHandle.

842
11 января 2010 года
sigmov
301 / / 16.09.2008
Цитата: hardcase
Вполне разумно. Зачем создавать указатель на ссылочный тип? ;) Но с генериками да, вышел косячокс, впрочим есть замечательный тип GCHandle.



Иногда и на ссылочный нужен.

Допустим конструкция извлекающая jй столбец прямоугольного массива

Код:
generic<class T> value struct Box
{
    T item;
};
public ref struct Special abstract sealed
{
    generic<class T> static array<T>^ GetColumn(array<T,2>^ Array, int j)
    {
        int n = Array->GetLength(0);
        int m = Array->GetLength(1);
       
        array<T>^ Return = gcnew array<T>(n);

        pin_ptr<T> p = &Array[0,j];
        pin_ptr<T> r = &Return[0];

        for(Box<T> *_It = (Box<T>*)r, *_It_end = _It + n, *_It_src = (Box<T>*)p; _It<_It_end; *_It = *_It_src, _It++, _It_src+=m);

        return Return;
    }
};


На С# ее никак не повторишь.
А через индексаторы это делать - в 2 раза дольше будет.

И что самое приятное совершенно неважно, ссылочный это тип или не ссылочный - все будет работать!
5
11 января 2010 года
hardcase
4.5K / / 09.08.2005
Цитата: sigmov
Иногда и на ссылочный нужен.

Допустим конструкция извлекающая jй столбец прямоугольного массива

Для получения строки двумерного массива есть обощенный код:

 
Код:
public static T[] GetRow<T>(T[,] a, int index) {
    int rows = a.GetLength(0);
    int cols = a.GetLength(1);
    if (rows <= index)
        throw new IndexOutOfRangeException();
    T[] result = new T[cols];
    int len = Buffer.ByteLength(result);
    Buffer.BlockCopy(a, len * index, result, 0, len);
    return result;
}

Что-то похожее для получения столбца, признаюсь, не придумал.



З.Ы. Ваш нэйминг - адская жесть.
842
11 января 2010 года
sigmov
301 / / 16.09.2008
Цитата: hardcase
Для получения строки двумерного массива есть обощенный код:



Который выдает исключение в том случае, если массив содержит не примитивы:
Необработанное исключение: System.ArgumentException: Объект должен быть массивом примитивов.
Имя параметра: src в System.Buffer.BlockCopy(Array src, Int32 srcOffset, Array dst, Int32 dstOffset, Int32 count)


Да еще и проигрывает по скорости обычным индексаторам result[j]=a[index,j]

Цитата: hardcase
З.Ы. Ваш нэйминг - адская жесть.



Да грешу этим.

842
11 января 2010 года
sigmov
301 / / 16.09.2008
Вообщем вывод:
1) Пишу сборку на C#
2) Критическую функции пишу на MC++
3) dlasm разбираю обе сборки. заменяю несколько функций в Шарповой сборке на @быстрые@ аналоги из функции MC++ сборки
4) собираю сборку
5
11 января 2010 года
hardcase
4.5K / / 09.08.2005
Цитата: sigmov
Который выдает исключение в том случае, если массив содержит не примитивы:
Необработанное исключение: System.ArgumentException: Объект должен быть массивом примитивов.
Имя параметра: src в System.Buffer.BlockCopy(Array src, Int32 srcOffset, Array dst, Int32 dstOffset, Int32 count)


Да еще и проигрывает по скорости обычным индексаторам result[j]=a[index,j]


Признаюсь, не проверял. :(


Цитата: sigmov
Вообщем вывод:
1) Пишу сборку на C#
2) Критическую функции пишу на MC++
3) dlasm разбираю обе сборки. заменяю несколько функций в Шарповой сборке на @быстрые@ аналоги из функции MC++ сборки
4) собираю сборку

Может быть лучше использовать .net модуль (netmodule) создаваемый MC++, а при компиляции C# проекта подключать его (где-то на форуме я рассказывал, как подключить). Правда, получится не один а два файла в итоге.

842
11 января 2010 года
sigmov
301 / / 16.09.2008
Цитата: hardcase
Может быть лучше использовать .net модуль (netmodule) создаваемый MC++, а при компиляции C# проекта подключать его (где-то на форуме я рассказывал, как подключить). Правда, получится не один а два файла в итоге.



А Net модуль на MC++ не утянет с собой "код инфраструктуры MC++"?

5
11 января 2010 года
hardcase
4.5K / / 09.08.2005
Цитата: sigmov
А Net модуль на MC++ не утянет с собой "код инфраструктуры MC++"?


Фиг знает.
А разве эти "лишние" 24 КБ сильно мешают?

341
12 января 2010 года
Der Meister
874 / / 21.12.2007
Цитата: sigmov
Допустим конструкция извлекающая jй столбец прямоугольного массива... (код пропускаем)
На С# ее никак не повторишь.
А через индексаторы это делать - в 2 раза дольше будет.

Да нет, не более 12% медленнее, да и то за счёт проверки границ массива во время исполнения.

842
12 января 2010 года
sigmov
301 / / 16.09.2008
Цитата: Der Meister
Да нет, не более 12% медленнее, да и то за счёт проверки границ массива во время исполнения.



У меня получилось что на 40%.
Уж не знаю почему, но вот так.

Допускаю из-за того что индексация [i,j] развертвается как:
1) проверка границ
2) (адрес начала массива)+i*(число эл-тов в строке)+j

А в цикле который я привел отсутствует как проверка границ, так и умножение для получения следующего нужного эл-та.

5
12 января 2010 года
hardcase
4.5K / / 09.08.2005
Цитата: sigmov
У меня получилось что на 40%.
Уж не знаю почему, но вот так.

Допускаю из-за того что индексация [i,j] развертвается как:
1) проверка границ
2) (адрес начала массива)+i*(число эл-тов в строке)+j

А в цикле который я привел отсутствует как проверка границ, так и умножение для получения следующего нужного эл-та.

Проверка в дотнете не учитывает объявленную размерность, проверяется попадание в массив.
Т.е. формула адреса будет примерно такая:
адрес_массива + i * j * размер_элемента
проверка попадания:
i * j < общая_длина

341
12 января 2010 года
Der Meister
874 / / 21.12.2007
Цитата: sigmov
У меня получилось что на 40%.
Уж не знаю почему, но вот так.

Ну вот проектец и ложик профайлера.

Реклама на сайте | Обмен ссылками | Ссылки | Экспорт (RSS) | Контакты
Добавить статью | Добавить исходник | Добавить хостинг-провайдера | Добавить сайт в каталог