PDA

View Full Version : منظور از كلمه packed چيست؟



BORHAN TEC
سه شنبه 18 اسفند 1388, 14:48 عصر
سلام.
در حال مطالعه يك كد بودم كه به تعريف زير رسيدم. مشكل اينجاست كه نميدونم منظور از كلمه packed در اين كد چيه. ميشه راهنمايي كنيد؟

type
_DEV_BROADCAST_HDR = packed record
dbch_size: DWORD;
dbch_devicetype: DWORD;
dbch_reserved: DWORD;
end;

Mahmood_M
سه شنبه 18 اسفند 1388, 19:54 عصر
براي درك بهتر اين موضوع بايد كمي با ساختار حافظه آشنا باشيد ! و مفهوم DWord-Aligned !

اگر بخوايم به صورت ساده بگيم :
وقتي يك داده عددي مثل Integer تعريف ميشه يك خانه ي حافظه با اندازه ي 4 ( اندازه ی نوع DWORD ) در حافظه براش درنظر گرفته ميشه ، حالا اگه مثلا يك متغير Int64 تعريف كنيد اندازش ميشه 8 ، حافظه كامپيوتر بدون اينكه در نظر بگيره در اين خانه چه نوع اطلاعاتي قرار گرفته يك آدرس براي كل اون 8 بايت به عنوان يك خانه ي حافظه قرار ميده ...
وقتي يك ركورد ثبت مي كنيد در حالت عادي ركورد براي اعضاي خودش يك حافظه ي جدا در نظر مي گيره ، مثلا در مثالي كه شما قرار داديد ، نوع DWord اندازه اي برابر 4 رو اشغال مي كنه و Record هم براي اعضاي خودش سه خانه ي 4 تايي با 3 آدرس مجزا در نظر مي گيره تا دسترسي به اونها سريعتر باشه ...
وقتي يك ركورد به صورت Pack شده تعريف ميشه ، برنامه سعي ميكنه كه همه اعضا رو در يك خانه ي حافظه با يك آدرس قرار بده ، در اين صورت حجم خالي در حافظه باقي نمي مونه ولي به خاطر آدرس مشابه براي اعضاي Record ممكنه دسترسي به داده هاي اونها كمي زمان بيشتري نياز داشته باشه ...
پس استفاده از عبارت Packed باعث ميشه كه حجم كمتري از حافظه اشغال بشه اما سرعت يا Performance كمي كاهش پيدا مي كنه ...
اميدوارم منظور رو رسونده باشم ...
اما در مثالي كه قرار داديد ، نوع Packed با نوع عادي Record تفاوتي در ميزان حجم مصرفي ندارن چون براي هر نوع متغير DWORD مقدار 4 بايت فضا نياز هست ، تنها فرقش با ركورد Pack نشده اينه كه هر سه متغير در يك خانه ي حافظه و با يك آدرس قرار مي گيرند ولي در هر دو حالت مقدار فضاي مصرفي ميشه 12 ...

عبارت Packed رو مي تونيد براي يك آرايه يا هر نوع داده كه چند عضو مجزا داره استفاده كنيد ، مثلا براي يك آرايه به صورت زير ميشه استفاده كرد :
PA : packed array[0..9] of Integer;
اگر نياز بود بگيد تا با چند مثال بهتر منظور رو بيان كنم ...

موفق باشيد ...

gbg
سه شنبه 18 اسفند 1388, 19:59 عصر
خب دوستومن خیلی خوب و کامل گفت
اگه نخوام گنگ بگم وقتی record رو pack می کنیم اعضا به صورت خطی و مانند آرایه پشت سر هم قرار میگیرن و حافظه هدر نمیره ولی سرعت دسترسی میاد پایین

BORHAN TEC
چهارشنبه 19 اسفند 1388, 14:35 عصر
اگر نياز بود بگيد تا با چند مثال بهتر منظور رو بيان كنم ...
اگه اين كار رو بكنيد خيلي خوب ميشه!!!

Mahmood_M
چهارشنبه 19 اسفند 1388, 15:27 عصر
اگه اين كار رو بكنيد خيلي خوب ميشه!!!
ابتدا بايد با تابع SizeOf آشنا بشيد ، البته شايد آشنا هستيد ، ولي توضيح كوتاهي ميدم :
اين تابع مقدار فضاي اشغالي از حافظه رو براي يك متغير يا Type برمي گردونه ، به وسيله اين تابع مي تونيد مقدار حافظه ي اشغالي رو نمايش بديم ...
ابتدا يك متغير از نوع char تعريف كنيد و با تابع SizeOf فضاي اشغاليش رو ببينيد ، اين فضا برابر 1 هست ، حالا براي يك متغير Integer اين كار رو انجام بديد مي بينيد كه فضاي اشغالي اون برابر 4 هست ...
يك ركورد به صورت زير ايجاد كنيد :
type
MyRecord = Record
Ch : Char;
I : Integer;
end;
حالا با استفاده از تابع SizeOf مقدار فضاي اشغالي اين ركورد رو ببينيد ، برابر 8 هست ، در حالي كه متغير از نوع char فضايي برابر 1 و متغير از نوع Integer فضايي برابر 4 اشغال مي كنه و مجموعشون بايد بشه 5 ...
توضيح بهتر :
مفوم DWord-Alignment همين هست كه براي هر متغير يك خانه ي حافظه ي با مقدار مضرب چهار در نظر گرفته ميشه ، در ركورد بالا براي متغير char بدون توجه به نوع char يك خانه ي حافظه ي با فضاي 4 بايت ايجاد ميشه و يك آدرس بهش تعلق مي گيره ، و براي متغير Integer هم به همين ترتيب ، در اين صورت سه بايت از چهار بايت درنظر گرفته شده براي متغير char بي استفاده باقي مي مونه اما براي ساير برنامه ها يا متغير ها يا ... قابل استفاده نيست ! ، اين باعث ميشه كه فضاي بيشتري اشغال بشه ، اما اين نوع ايجاد خانه در حافظه باعث ميشه كه اطلاعات در يك آدرس مشترك قرار نگيرند و دسترسي به اونها سريعتر انجام بشه ...

حالا همون ركورد رو به صورت Packed تعريف كنيد :
type
MyRecord = Packed Record
Ch : Char;
I : Integer;
end;
اگر با SizeOf مقدارش رو بگيريد مي بينيد كه برابر 5 هست ، يك خانه ي حافظه با حجم 5 بايت تعريف ميشه و تمام اطلاعات ركورد درونش قرار مي گيره ، هم متغير char و هم متغير Integer ، در اينصورت فضاي كمتري اشغال ميشه اما به خاطر مشترك بودن آدرسها و كنار هم قرار گرفتن اطلاعات دسترسي به اونها و درواقع تفكيك و شناختن اونها كمي زمان مي بره ...

يك نكته ي مهم : خانه هاي ايجاد شده براي يك متغير به صورت dword - aligned نيستند و به اندازه فضاي لازم براي همون متغير اند ، مثلا براي char برابر 1 بايت يا براي Integer برابر 4 بايت يا int64 برابر 8 بايت ...

يك نكته : الآن به پاسخ اولم نگاه مي كنم يك اشتباه كوچيك توي توضيحات وجود داره كه بايد ويرايش بشه ...

اميدوارم مفيد بوده باشه ...

موفق باشيد ...