How does one have arrays in a Matlab share the same memory

조회 수: 3 (최근 30일)
Patrick Ford
Patrick Ford 2016년 7월 6일
편집: James Tursa 2016년 7월 15일
Greetings, Is there a simple means in Matlab for two arrays to share the same data space? In other words letting A be a N by M array of type int32 and B being a NxMX4 type int8. In C I would do this with pointers. Thank you

채택된 답변

Stephen23
Stephen23 2016년 7월 6일
편집: Stephen23 2016년 7월 6일
It seems to be possible to do this with memmapfile:
myData = int8(1:10)';
fileID = fopen('records.dat','w');
fwrite(fileID, myData,'int8');
fclose(fileID);
m1 = memmapfile('records.dat','Writable',true,'Format','int8');
m2 = memmapfile('records.dat','Writable',true,'Format','int32');
and checking the original data:
>> m1.Data
ans =
1
2
3
4
5
6
7
8
9
10
>> m2.Data
ans =
67305985
134678021
Now we change one of the int32 values:
>> m2.Data(2) = m2.Data(2) + 1;
and check what happened to the int8 data:
>> m1.Data
ans =
1
2
3
4
6
6
7
8
9
10
So, the 5 has changed into a 6, proving that memmapfile can be used to achieve your goal. You will need to play around with byte order, dimensions, and whatnot, but it seems to be possible to make this happen.
  댓글 수: 4
Stephen23
Stephen23 2016년 7월 6일
편집: Stephen23 2016년 7월 6일
The easiest solution may be to write a mex function to do this.
James Tursa
James Tursa 2016년 7월 15일
As Stephen points out, this could be done with a mex routine but with a couple of caveats:
1) You would need to make the shared data copy of a different class using a mex routine that hacks into the variable mxArray structure since there are no existing official MATLAB or mex API functions that will do this. E.g., my typecastx function from the FEX can do this. MATLAB's typecast function can't be used for this since it produces a deep data copy.
2) ALL of the data element changes/updates would have to be done at the mex level so that you could modify values in-place without causing an unsharing data copy to take place. I.e., any data element change that you would make at the m-file level will see the shared variable status and invoke the copy-on-write mechanism and first unshare the variables ... which is precisely what you are trying to avoid.

댓글을 달려면 로그인하십시오.

추가 답변 (3개)

Thorsten
Thorsten 2016년 7월 6일
You cannot do that in Matlab.
  댓글 수: 1
Patrick Ford
Patrick Ford 2016년 7월 6일
I was considering trying libpointer without calling any external C routine. It seems that may work, but it depends on how Matlab manages its memory. Could I depend on the pointer remaining valid or would I need to keep updating it each time I accessed it?

댓글을 달려면 로그인하십시오.


Philip Borghesani
Philip Borghesani 2016년 7월 7일
A libpointer can be (mis)used to do this but I am not sure it will help in the long run due to the overall performance of and copying out (accessing ptr.value) needed with libpointers.
pi8=libpointer('int8Ptr',1:16)
pi16=libpointer('voidPtr',pi8)
pi16.setdatatype('int16Ptr',1,8)
pi16.value(3)=100;
pi8.value
ans =
1×16 int8 row vector
1 2 3 4 100 0 7 8 9 10 11 12 13 14 15 16
  댓글 수: 1
Patrick Ford
Patrick Ford 2016년 7월 9일
Thank you for the answer. The overhead issue will be if using pointers or the ram disk overhead is significantly less than copying arrays. Since the arrays have the potential the potential of multiple megabytes or higher, I suspect the frequent updating would be a bottleneck. I did something similar when I was using IDL and C. The address to the arrays were not consistently set in memory, so I had to allocate the pointers each time before accessing the array then deallocate, which was considerably faster than copying, and used less ram too.

댓글을 달려면 로그인하십시오.


Patrick Ford
Patrick Ford 2016년 7월 13일
Well, I ran into another issue. What I want to do is have an array in MatLab, say a 3D of size (A,B,C) of type int16 or int32 and have basically a pointer to the first address so I can access the entire array as a string of bytes or int8 with a size of A*B*C. If I can set this up, would need to just know the addressing scheme so I would know the where each AxB matrices starts and ends.
So I can either reference as a 3D int32 or 1D int8 (which would be size of A*B*C*4 bytes)
The libpointer allows me to address the same space as int32 or int8. But I cannot create a pointer to an array defined in MatLab.
Example:
a = zeros(10,10) px = libpointer('voidPtr', a)
Altering 'a' does not change px.value, although px.value is the same type and size as a.
  댓글 수: 1
James Tursa
James Tursa 2016년 7월 15일
편집: James Tursa 2016년 7월 15일
In your libpointer example, the value that libpointer creates is a deep data copy of "a". There would be no way to use this libpointer, even in a mex routine, to alter any values in "a". E.g.,
>> a = zeros(1,5)
a =
Structure address = 72ca8b0
m = 1
n = 5
pr = 24545770
pi = 0
0 0 0 0 0
>> px = libpointer('voidPtr', a)
px =
libpointer
>> px.value
ans =
Structure address = 72ca178
m = 1
n = 5
pr = 206aee80
pi = 0
0 0 0 0 0
You can see that the pr data pointers for a and px.value are different, which means that they are not shared data copies of each other.
To have variables of different classes sharing memory and being able to alter one without automatic unsharing, see my mex comment above. You would probably need to employ something like my typecastx FEX submission to accomplish it. Or maybe just pass in the int16 or int32 and manipulate the data elements in-place in the mex routine as int8 without ever creating a shared int8 version of the variable.

댓글을 달려면 로그인하십시오.

카테고리

Help CenterFile Exchange에서 Data Type Conversion에 대해 자세히 알아보기

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by