2013-12-10 5 views
3

Я часто оптимизирую некоторые подпрограммы matlab, реализуя их в mex. Это прекрасно работает до сих пор - но при создании возврата mxArray он получает preinitialized, поскольку я строю его с mxCreateNumericArray.
В большинстве моих работ мне не нужна память, которая будет предварительно распределена (обнулена). Так грустно - я не могу найти подходящую команду для этой цели (выделение памяти без обнуления).Создание mxArray * без * выделения/инициализации памяти

Так что мой вопрос можно ответить двумя способами:

  1. Какая команда у меня призвать к созданию mxArray без обнуления содержимого?
  2. Как я могу построить mxArray без выделения памяти для PrPi) -field, которое я позже выделил бы на mxMalloc.

Одна идея заключается в том, чтобы построить массив с размером (0,0) - но это окончательное решение?

+1

Не уверен, что это помогает, но, возможно, вы можете получить некоторое вдохновение от вопроса [Быстрый способ инициализации массивов] (http://stackoverflow.com/questions/14169222/faster-way-to-initialize-arrays-via -empty-matrix-multipication-matlab) –

ответ

2

Я думаю, построение матрицы размера (0,0) так же близко, как и до своего рода «пустого» конструктора. После этого вам придется изменить размер массива с помощью mxMalloc или mxRealloc.

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

+0

Привет, это звучит как-то ясно.Я попытался создать массив 12345 x 12345 с mxCreateNumericArray, результатом которого было 5,7992 секунды по времени против создания с 0,0 и использование mxMalloc и mxSetDimensions для тех же данных и размера, что привело к 5.8946 секундам. Это странно, не так ли? (В то же время выполняется некоторое сжатие, точно так же для обоих вызовов.) –

+0

Это странно, да. Являются ли тайминги сопоставимыми для нескольких тестовых прогонов? Если это так, кажется, что Matlab делает довольно хорошую работу ... – sebastian

+0

Я использовал последние несколько часов для тестирования различных методов. В сочетании с вашими линиями здесь, я думаю, я могу ответить на свой вопрос сам, и поэтому я вскоре опубликую свои результаты в качестве ответа. Спасибо –

2

С этими линиями из Себастьяна я играл. Я думаю, следующие строки показывают ответ на мой вопрос.
На словах - даже при нулевом пространстве результат получается быстрым.
С моей текущего приложения Я проверил четыре различных сценария:

  1. plhs[0] = mxCreateNumericArray(targetDimCount, targetDims, targetClass, mxREAL);
  2. plhs[0] = mxCreateNumericArray(0, 0, targetClass, mxREAL); mxSetData(plhs[0],mxMalloc(destLen_in_Bytes));
  3. plhs[0] = mxCreateNumericArray(0, 0, targetClass, mxREAL); mxSetData(plhs[0],mxRealloc(mxGetData(plhs[0]),destLen_in_Bytes));
  4. plhs[0] = mxCreateUninitNumericArray(targetDimCount, targetDims, targetClass, mxREAL);

в результате чего эти моменты времени (для выделенных матриц размера, указанных в колонке один)

size  time 1  time 2  time 3  time 4 

1000  0.037401  0.037263  0.039294  0.037628 
2000  0.14906  0.14937  0.15278  0.14917 
3000  0.33497  0.33449  0.34601  0.33749 
4000  0.61207  0.60546  0.61563  0.60086 
5000  0.94057  0.93076  0.96147  0.95723 
6000  1.3497  1.3475  1.3794  1.3559 
7000  1.837  1.8265  1.8776  1.846 
8000  2.398  2.3893  2.4625  2.3885 
9000  3.0264  3.047  3.1374  3.0339 
10000  3.7658  3.7677  3.8392  3.7862 
20000 15.208  14.968  15.404  15.143 
30000 13.583  13.58  13.955  13.648 
50000 13.291  13.236  13.535  13.478 

С точки зрения этих чисел, мое мнение таково, что перераспределение - это плохая идея (но не так уж плохо, как показывают сроки), и обнуление значений не является очень большим эффектом. Хорошо - еще можно удивляться поведению от 10000 до 30000, но это было бы более научным. Использование malloc (только для целей тестирования) не работает, поскольку выделенное хранилище должно быть для plhs - и оно выходит из строя, если хранилище не распределено по mx ***

+1

Я сам пытался решить эту проблему и не нашел чистого решения. Было бы целесообразно использовать тайминги для использования malloc() вместо mxMalloc() (а не того, что вы должны делать это на практике), так как тайминги предполагают, что mxMalloc перетаскивает всю выделенную память через кеш (поскольку код становится медленнее, поскольку выделенные размер увеличивается). – user664303

+0

Также попробуйте использовать mxSetPr вместо mxSetData, чтобы узнать, не имеет значения. – user664303

+1

@ user664303 - Я не могу найти разницу в использовании mxSetPr - и из документа он использует только введенный указатель, а не указатель на void. –

1

Другим возможным вариантом может быть недокументированная функция mxFastZeros. Это один из многих undocumented mex functions. Вы можете прочитать о его использовании в this Matlab Central answer. Мне было бы интересно узнать, не делает ли что-то другое, просто создавая матрицу нулевого размера.

Смежные вопросы