هل يمكن تخصيص الحلقة التالية؟
-
22-09-2019 - |
سؤال
لدي حلقة من أجل أداء الوظيفة التالية:
خذ M × 8 مصفوفة و:
- اقسمها إلى كتل من عناصر الحجم 512 (بمعنى x في 8 من المصفوفة == 512 ، ويمكن أن يكون عدد العناصر 128،256،512،1024،2048)
- إعادة تشكيل الكتلة إلى 1 × 512 (عدد العناصر) مصفوفة.
- خذ آخر 1/4 من المصفوفة ووضعها في المقدمة ،
على سبيل المثالData = [Data(1,385:512),Data(1,1:384)];
ما يلي هو الكود الخاص بي:
for i = 1 : NumOfBlock
if i == 1
Header = tempHeader(1:RowNeeded,:);
Header = reshape(Header,1,BlockSize); %BS
Header = [Header(1,385:512),Header(1,1:384)]; %CP
Data = tempData(1:RowNeeded,:);
Data = reshape(Data,1,BlockSize); %BS
Data = [Data(1,385:512),Data(1,1:384)]; %CP
start = RowNeeded + 1;
end1 = RowNeeded * 2;
else
temp = tempData(start:end1,:);
temp = reshape(temp,1,BlockSize); %BS
temp = [temp(1,385:512),temp(1,1:384)]; %CP
Data = [Data, temp];
end
if i <= 127 & i > 1
temp = tempHeader(start:end1,:);
temp = reshape(temp,1,BlockSize); %BS
temp = [temp(1,385:512),temp(1,1:384)]; %CP
Header = [Header, temp];
end
start = end1 + 1;
end1=end1 + RowNeeded;
end
سيستغرق تشغيل هذه الحلقة بعنصر 5 ملايين ساعة أكثر من ساعة واحدة. أحتاج إلى أن تكون بأسرع ما يمكن (في ثانية). هل هذه الحلقة قادرة على أن تكون متجهًا؟
المحلول 4
مرة أخرى ، أود أن أشكر Amro على إعطائي فكرة عن كيفية حل سؤالي. آسف لعدم توضيح نفسي في السؤال.
هذا هو الحل لمشكلتي:
%#BS CDMA, Block size 128,512,1024,2048
BlockSize = 512;
RowNeeded = BlockSize / 8;
TotalRows = size(tempData);
TotalRows = TotalRows(1,1);
NumOfBlock = TotalRows / RowNeeded;
CPSize = BlockSize / 4;
%#spilt into blocks
Header = reshape(tempHeader',[RowNeeded,8, 128]);
Data = reshape(tempData',[RowNeeded,8, NumOfBlock]);
clear tempData tempHeader;
%#block spread & cyclic prefix
K = zeros([1,BlockSize,128],'single');
L = zeros([1,BlockSize,NumOfBlock],'single');
for i = 1:NumOfBlock
if i <= 128
K(:,:,i) = reshape(Header(:,:,i),[1,BlockSize]);
K(:,:,i) = [K((CPSize*3)+1:BlockSize),K(1:CPSize*3)];
end
L(:,:,i) = reshape(Data(:,:,i),[1,BlockSize]);
L(:,:,i) = [L((CPSize*3)+1:BlockSize),L(1:CPSize*3)];
end
نصائح أخرى
بناءً على وصف وظيفتك ، إليك ما توصلت إليه:
M = 320; %# M must be divisble by (numberOfElements/8)
A = rand(M,8); %# input matrix
num = 512; %# numberOfElements
rows = num/8; %# rows needed
%# equivalent to taking the last 1/4 and putting it in front
A = [A(:,7:8) A(:,1:6)];
%# break the matrix in blocks of size (x-by-8==512) into the third dimension
B = permute(reshape(A',[8 rows M/rows]),[2 1 3]);
%'# linearize everything
B = B(:);
قد يساعد هذا الرسم التخطيطي في فهم ما سبق:
قد تكون الخلفية قد تساعد أو لا تساعد. ما سيساعد هو معرفة أين عنق الزجاجة. استخدم profiler كما هو موضح هنا:
http://blogs.mathworks.com/videos/2006/10/19/profiler-find-code-bottlenecks/
سيكون من الرائع أن تخبر ما تحاول القيام به (أعتقد أن بعض المحاكاة في الأنظمة الديناميكية ، ولكن من الصعب معرفة ذلك).
نعم ، بالطبع يمكن أن تكون متجهًا: كل كتلك هي في الواقع أربع كتل فرعية ؛ باستخدام مؤشراتك (غير قياسية للغاية):
1...128, 129...256, 257...384, 385...512
يجب أن يفعل كل نواة/مؤشر ترابط/أي شيء على الإطلاق-ما يلي:
I = ThreadIdx يتراوح بين 0 و 127 temp = data [1 + i] data [1 + i] = data [385 + i] data [385 + i] = data [257 + i] data [257 + i] = data [129 + i] البيانات [129 + i] = درجة الحرارة
يجب عليك بالطبع أيضًا موازية على الكتل ، وليس فقط.