Struct to double[]
От: Аноним  
Дата: 23.06.14 13:06
Оценка:
Нужно быстро преобразовать структуру в массив double.
вот код


    [DllImport("msvcrt.dll", SetLastError = false, CallingConvention= CallingConvention.Cdecl)]
    static extern unsafe IntPtr memmove(double* dest, MyStruct* src, int count);
///.......
    // MyStruct - размер 128
    MyStruct data = GetData();
    double[] array = new double[128];
    fixed (MyStruct* myStruct = &data)
    fixed (double* myArray = array) 
       memmove(myArray, myStruct, 128);


Есть ли более быстрое решение?
Re: Struct to double[]
От: hardcase Пират http://nemerle.org
Дата: 23.06.14 13:25
Оценка:
Здравствуйте, Аноним, Вы писали:

А>Есть ли более быстрое решение?


Есть готовый велосипед: Marshal.Copy
/* иЗвиНите зА неРовнЫй поЧерК */
Re: Struct to double[]
От: hardcase Пират http://nemerle.org
Дата: 23.06.14 13:30
Оценка: +1
Здравствуйте, Аноним, Вы писали:

А>Нужно быстро преобразовать структуру в массив double.

А>вот код

Ваш код можно сократить и исправить ошибку.


    [DllImport("msvcrt.dll", SetLastError = false, CallingConvention= CallingConvention.Cdecl)]
    static extern unsafe IntPtr memmove(ref double dest, ref MyStruct src, int count);
///.......
    // MyStruct - размер 128
    MyStruct data = GetData();
    double[] array = new double[128];
    memmove(ref array[0], ref myStruct, array.Length * sizeof(double));
/* иЗвиНите зА неРовнЫй поЧерК */
Re[2]: Struct to double[]
От: Sinix  
Дата: 23.06.14 13:50
Оценка:
Здравствуйте, hardcase, Вы писали:

H>Ваш код можно сократить и исправить ошибку.

А разве не так:
    [DllImport("msvcrt.dll", SetLastError = false, CallingConvention= CallingConvention.Cdecl)]
    static extern unsafe IntPtr memmove([Out] ref double dest, [In] ref MyStruct src, int count);

?

Кстати, с .net native отладка интероп-кода стала немного проще (по ссылке есть в том числе и про [Out]).
Re[2]: Struct to double[]
От: Аноним  
Дата: 23.06.14 13:52
Оценка:
Здравствуйте, hardcase, Вы писали:

H>Здравствуйте, Аноним, Вы писали:


А>>Есть ли более быстрое решение?


H>Есть готовый велосипед: Marshal.Copy


Marshal.Copy??? вы уверены???
А пример можно?
Re[3]: Struct to double[]
От: Аноним  
Дата: 23.06.14 14:01
Оценка:
Здравствуйте, Sinix, Вы писали:

S>Здравствуйте, hardcase, Вы писали:


H>>Ваш код можно сократить и исправить ошибку.

S>А разве не так:
S>
S>    [DllImport("msvcrt.dll", SetLastError = false, CallingConvention= CallingConvention.Cdecl)]
S>    static extern unsafe IntPtr memmove([Out] ref double dest, [In] ref MyStruct src, int count);
S>

S>?

S>Кстати, с .net native отладка интероп-кода стала немного проще (по ссылке есть в том числе и про [Out]).


Поясните пожалуйста — использование атрибутов не уменьшает производительность? Неужели на разбор атрибутов не тратится(хоть и очень мало) ресурсы CPU?
Мне всегда казалось unsafe код нужен для минимизации задержки вышеописанных действий если в этом есть смысл...
Re[3]: Struct to double[]
От: hardcase Пират http://nemerle.org
Дата: 23.06.14 14:12
Оценка:
Здравствуйте, Sinix, Вы писали:

S>Кстати, с .net native отладка интероп-кода стала немного проще (по ссылке есть в том числе и про [Out]).


Так мы же не строки маршаллим, атрибуты должны быть In/Out излишни.
/* иЗвиНите зА неРовнЫй поЧерК */
Re[4]: Struct to double[]
От: hardcase Пират http://nemerle.org
Дата: 23.06.14 14:15
Оценка:
Здравствуйте, Аноним, Вы писали:

А>Поясните пожалуйста — использование атрибутов не уменьшает производительность? Неужели на разбор атрибутов не тратится(хоть и очень мало) ресурсы CPU?


Этими атрибутами интересуется .NET при компиляции в машкод вызовы таких функций.
/* иЗвиНите зА неРовнЫй поЧерК */
Re[3]: Struct to double[]
От: hardcase Пират http://nemerle.org
Дата: 23.06.14 14:18
Оценка: +1
Здравствуйте, Аноним, Вы писали:

А>Marshal.Copy??? вы уверены???

А>А пример можно?

IntPtr можно получить из GCHandle (это "safe" аналог конструкции fixed).
Только писанины довольно много
/* иЗвиНите зА неРовнЫй поЧерК */
Re[4]: Struct to double[]
От: Sinix  
Дата: 23.06.14 15:24
Оценка:
Здравствуйте, hardcase, Вы писали:

H>Так мы же не строки маршаллим, атрибуты должны быть In/Out излишни.

Они не то чтобы излишни, скорее позволяют пропустить при маршаллинге часть операций. Для каких типов это делается, для каких нет — темна вода во облацех нигде не документировано. Точнее,

Сочетание атрибутов InAttribute и OutAttribute особенно удобно при работе с массивами и форматированными непреобразуемыми типами. Вызывающие объекты воспринимают изменения, внесенные в эти типы вызываемыми объектами, только когда применяются оба атрибута. Поскольку для этих типов необходимо копирование в процессе маршалинга, для уменьшения числа ненужных копий используются атрибуты InAttribute и OutAttribute

и в принципе всё.

Если ничего не путаю (с интеропом практически не возился) до .net native проверить результирующий код можно было только подрубанием отладчика и изучением вывода jit.
Re[4]: Struct to double[]
От: Sinix  
Дата: 23.06.14 15:27
Оценка:
Здравствуйте, Аноним, Вы писали:

А>Поясните пожалуйста — использование атрибутов не уменьшает производительность? Неужели на разбор атрибутов не тратится(хоть и очень мало) ресурсы CPU?

А>Мне всегда казалось unsafe код нужен для минимизации задержки вышеописанных действий если в этом есть смысл...

Атрибуты учитываются только при jit-компиляции, она выполняется один раз за время работы программы. Есть смысл или нет, проверить просто: пишем код, замеряем время
Re[4]: Struct to double[]
От: Аноним  
Дата: 23.06.14 16:30
Оценка:
Здравствуйте, hardcase, Вы писали:

H>Здравствуйте, Аноним, Вы писали:


А>>Marshal.Copy??? вы уверены???

А>>А пример можно?

H>IntPtr можно получить из GCHandle (это "safe" аналог конструкции fixed).

H>Только писанины довольно много

Но в таком случае тактов больше чем в начальном примере.
Сначала создаем структуру GCHandle(дорогостоящая операция когда борьба идет за микросекунды) потом копируем через Marshal.Copy туда данные. А вопрос стоит: как можно по производительности быстрее написать?....
Re[2]: Struct to double[]
От: Аноним  
Дата: 23.06.14 16:54
Оценка:
Здравствуйте, hardcase, Вы писали:

H>Здравствуйте, Аноним, Вы писали:


А>>Нужно быстро преобразовать структуру в массив double.

А>>вот код

H>Ваш код можно сократить и исправить ошибку.


H>

H>    [DllImport("msvcrt.dll", SetLastError = false, CallingConvention= CallingConvention.Cdecl)]
H>    static extern unsafe IntPtr memmove(ref double dest, ref MyStruct src, int count);
H>///.......
H>    // MyStruct - размер 128
H>    MyStruct data = GetData();
H>    double[] array = new double[128];
H>    memmove(ref array[0], ref myStruct, array.Length * sizeof(double));
H>


Такая запись действительно производительней всего, особенно если заместо array.Length * sizeof(double) написать 128 на свой страх и риск!
Re[3]: Struct to double[]
От: hardcase Пират http://nemerle.org
Дата: 23.06.14 17:24
Оценка:
Здравствуйте, Аноним, Вы писали:


А>Такая запись действительно производительней всего, особенно если заместо array.Length * sizeof(double) написать 128 на свой страх и риск!


А массив из 128 даблов тогда зачем создаешь (я так понял 16 будет достаточно)?
/* иЗвиНите зА неРовнЫй поЧерК */
Re[4]: Struct to double[]
От: Аноним  
Дата: 24.06.14 05:14
Оценка:
Здравствуйте, hardcase, Вы писали:

H>Здравствуйте, Аноним, Вы писали:



А>>Такая запись действительно производительней всего, особенно если заместо array.Length * sizeof(double) написать 128 на свой страх и риск!


H>А массив из 128 даблов тогда зачем создаешь (я так понял 16 будет достаточно)?


Опечатка в типографии
Re: Struct to double[]
От: romangr Россия  
Дата: 24.06.14 06:56
Оценка: +2
Здравствуйте, <Аноним>, Вы писали:

А>Нужно быстро преобразовать структуру в массив double.

А>вот код

А>

А>    [DllImport("msvcrt.dll", SetLastError = false, CallingConvention= CallingConvention.Cdecl)]
А>    static extern unsafe IntPtr memmove(double* dest, MyStruct* src, int count);
А>///.......
А>    // MyStruct - размер 128
А>    MyStruct data = GetData();
А>    double[] array = new double[128];
А>    fixed (MyStruct* myStruct = &data)
А>    fixed (double* myArray = array) 
А>       memmove(myArray, myStruct, 128);
А>


А>Есть ли более быстрое решение?


А зачем вообще использовать memmove?
using System;
using System.Runtime.InteropServices;

namespace ConsoleApplication11
{
    class Program
    {
        static unsafe void Main(string[] args)
        {
            var str = new MyStruct(1024.0);
            var arr = new double[16];
            var pstr = &str;
            fixed (double* parr = &arr[0])
            {
                var pstr1 = (MyStruct*) parr;
                *pstr1 = *pstr; 
            }
            PrintArray(arr);
        }

        static void PrintArray(double[] array)
        {
            foreach (var item in array)
            {
                Console.WriteLine(item);
            }
        }
    }


    [StructLayout(LayoutKind.Sequential, Size=128)]
    public struct MyStruct
    {
        double Field1;
        double Field2;

        public MyStruct(double value)
        {
            Field1 = value;
            Field2 = value;
        }
    }
}
... << RSDN@Home (RF) 1.2.0 alpha 5 rev. 67>>
Re[2]: Struct to double[]
От: Аноним  
Дата: 25.06.14 06:37
Оценка:
Здравствуйте, romangr

  Вы писали
R>Здравствуйте, <Аноним>, Вы писали:

А>>Нужно быстро преобразовать структуру в массив double.

А>>вот код

А>>

А>>    [DllImport("msvcrt.dll", SetLastError = false, CallingConvention= CallingConvention.Cdecl)]
А>>    static extern unsafe IntPtr memmove(double* dest, MyStruct* src, int count);
А>>///.......
А>>    // MyStruct - размер 128
А>>    MyStruct data = GetData();
А>>    double[] array = new double[128];
А>>    fixed (MyStruct* myStruct = &data)
А>>    fixed (double* myArray = array) 
А>>       memmove(myArray, myStruct, 128);
А>>


А>>Есть ли более быстрое решение?


R>А зачем вообще использовать memmove?

R>

R>using System;
R>using System.Runtime.InteropServices;

R>namespace ConsoleApplication11
R>{
R>    class Program
R>    {
R>        static unsafe void Main(string[] args)
R>        {
R>            var str = new MyStruct(1024.0);
R>            var arr = new double[16];
R>            var pstr = &str;
R>            fixed (double* parr = &arr[0])
R>            {
R>                var pstr1 = (MyStruct*) parr;
R>                *pstr1 = *pstr; 
R>            }
R>            PrintArray(arr);
R>        }

R>        static void PrintArray(double[] array)
R>        {
R>            foreach (var item in array)
R>            {
R>                Console.WriteLine(item);
R>            }
R>        }
R>    }


R>    [StructLayout(LayoutKind.Sequential, Size=128)]
R>    public struct MyStruct
R>    {
R>        double Field1;
R>        double Field2;

R>        public MyStruct(double value)
R>        {
R>            Field1 = value;
R>            Field2 = value;
R>        }
R>    }
R>}
R>


Потому что вот такой код не будет собираться:
  Пример
    class Program
    {
        static MyStruct str = new MyStruct(1024.0);
        static unsafe void Main(string[] args)
        {
          //  var str = new MyStruct(1024.0);
            var arr = new double[16];
            var pstr = &str;
            fixed (double* parr = &arr[0])
            {
                var pstr1 = (MyStruct*)parr;
                *pstr1 = *pstr;
            }
            PrintArray(arr);
        }

        static void PrintArray(double[] array)
        {
            foreach (var item in array)
            {
                Console.WriteLine(item);
            }
        }
    }

    [StructLayout(LayoutKind.Sequential, Size = 128)]
    public struct MyStruct
    {
        double Field1;
        double Field2;

        public MyStruct(double value)
        {
            Field1 = value;
            Field2 = value;
        }
    }
Re[3]: Struct to double[]
От: SanyaVB  
Дата: 25.06.14 06:50
Оценка: +1
Здравствуйте, Аноним, Вы писали:

Что мешает написать вот это?

 fixed (MyStruct* pstr = &str)
Re[3]: Struct to double[]
От: romangr Россия  
Дата: 25.06.14 08:48
Оценка:
Здравствуйте, <Аноним>, Вы писали:

А>Здравствуйте, romangr


А>Потому что вот такой код не будет собираться:

А>
А>    class Program
А>    {
А>        static MyStruct str = new MyStruct(1024.0);
А>        static unsafe void Main(string[] args)
А>        {
А>          //  var str = new MyStruct(1024.0);
А>            var arr = new double[16];
А>            var pstr = &str;
А>            fixed (double* parr = &arr[0])
А>            {
А>                var pstr1 = (MyStruct*)parr;
А>                *pstr1 = *pstr;
А>            }
А>            PrintArray(arr);
А>        }

А>        static void PrintArray(double[] array)
А>        {
А>            foreach (var item in array)
А>            {
А>                Console.WriteLine(item);
А>            }
А>        }
А>    }
А>


В моем случае MyStruct лежит на стеке, ей не надо делать fixed.
В твоем — fixed требуется, т.к. статическое поле считается уже moveable variable.
Такой код будет работать:
        static MyStruct str = new MyStruct(1024.0);
        static unsafe void Main(string[] args)
        {
            //var str = new MyStruct(1024.0);
            var arr = new double[16];
            fixed(MyStruct* pstr = &str)
            fixed (double* parr = &arr[0])
            {
                var pstr1 = (MyStruct*) parr;
                *pstr1 = *pstr; 
            }
            PrintArray(arr);
        }
... << RSDN@Home (RF) 1.2.0 alpha 5 rev. 67>>
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.