next up previous contents index
Next: การแสดงคำสั่งในคอมพิวเตอร์ Up: คำสั่ง: ภาษาของคอมพิวเตอร์ Previous: การทำงานของคอมพิวเตอร์ฮาร์ดแวร์   Contents   Index

การเก็บตัวแปรการคำนวณในคอมพิวเตอร์ฮาร์ดแวร์

คอมพิวเตอร์ฮาร์ดแวร์ จะทำการคำนวณบนหน่วยความจำเล็กๆ ที่มีความเร็วสูงที่เรียกว่า รีจีสเตอร์ ผู้เขียนโปรแกรมสามารถใช้รีจีสเตอร์เหล่านี้ทำการคำนวณในขั้นตอนต่างๆ ซึ่งจะแตกต่างกับการเขียนโปรแกรมในภาษาระดับสูงที่สามารถนิยามตัวแปรได้หลากหลาย ที่รีจีสเตอร์ในฮาร์ดแวร์มีจำนวนจำกัด ในสถาปัตยกรรม MIPS มีจำนวนรีจีสเตอร์จำนวน 32 ตัว โดยแต่ละตัวขนาดมี 32 บิต ขนาดของ 32 บิตใน MIPS เรียกว่าหนึ่ง Word อย่างไรก็ตามการใช้งานรีจิสเตอร์เหล่านี้จะมีการแบ่งกลุ่มให้สามารถใช้งานได้ในลักษณะงานที่แตกต่างกัน

เหตุที่ในคอมพิวเตอร์ฮาร์ดแวร์มีจำนวนรีจีสเตอร์จำกัด นำมาสู่หลักการออกแบบที่สองได้แก่

Design Principle 2: Smaller is faster.

ในวงจรไฟฟ้าที่เป็นพื้นฐานของระบบ คอมพิวเตอร์ที่ทำงานโดยอาศัยการเคลื่อนที่ของอีเล็กตรอน ยิ่งระยะทางในการเคลื่อนที่มีน้อยเท่าไร ก็สามารถออกแบบวงจรให้ทำงานได้ความเร็วมากขึ้น วงจรที่มีขนาดเล็กก็สามารถสื่อถึงความซับซ้อนของวงจรด้วย ยิ่งระบบมีขนาดเล็ก และมีความซับซ้อนน้อยลงเท่าใด จะสามารถทำให้ทำงานได้เร็วขึ้น ในรูปของความเร็วสัญญาณนาฬิกา ในการระบุถึงตัวรีจีสเตอร์ต่างๆ จะใช้ตัวอักษรสองตัว เริ่มด้วยเครื่องหมาย $ เช่น $s0, $s1, $s2, $\ldots$ สำหรับ รีจิสเตอร์ที่เป็นตัวแปรในภาษา C และ ภาษา JAVA และ $t0, $t1, $\ldots$ สำหรับเป็นตัวแปรชั่วคราวในการคำนวณตามโปรแกรมที่ตัวแปลงภาษาจะใช้งานรีจีสเตอร์เหล่านี้

การแปลงชุดของภาษา C โดยใช้รีจีสเตอร์

หน้าที่ของตัวแปลงภาษาคือทำการแปลงตัวแปร ในภาษาระดับสูง เป็นการใช้งานในรีจีสเตอร์เพื่อทำการคำนวณ จากตัวอย่างที่แล้ว

f = (g + h) - (i + j);

ตัวแปรเป็น f, g, h, i, และ j ถูกกำหนดให้กับรีจีสเตอร์ $s0, $s1, $s2, $s3, และ $s4, ตามลำดับ จงเขียนโค๊ดของ MIPS

การแปลงภาษามีวิธีการคล้ายที่แล้วมา เพียงแต่ใช้งาน $t0 และ $t1 ในการเก็บตัวแปร

add $t0, $s1, $s2 # temporary variable t0 contains g + h
add $t1, $s3, $s4 # temporary variable t1 contains i + j
sub $s0, $t0, $t1 # f gets t0 - t1, which is (g + h)-(i + j)

ตัวแปรที่อยู่ในหน่วยความจำ

ในการเขียนโปรแกรม จะรองรับโครงสร้างข้อมูลที่มีลักษณะที่แตกต่างกันออกไป จากข้อมูลพื้นฐาน มาเป็นข้อมูลที่มีความสลับซับซ้อน เช่น ข้อมูลที่เป็นตาราง หรือ เป็นโครงสร้างในลักษณะต่างๆ ลักษณะข้อมูลดังกล่าวอาจมีขนาดมากกว่า ขนาดของรีจีสเตอร์ ทั้งสองตัวที่มีอยู่ หรือขนาดของข้อมูลในการคำนวณของโปรแกรมนั้นๆ อาจมีขนาดใหญ่มาก ซึ่งโปรเซสเซอร์จะเก็บข้อมูลไว้จำนวนไม่มากไว้ในรีจีสเตอร์ และ ข้อมูลส่วนใหญ่หรือทั้งหมดไว้ในหน่วยความจำหลัก

การคำนวณทางคณิตศาสตร์ในชุดคำสั่งของ MIPS ตัวแปรที่ทำการคำนวณจะต้องอยู่ในรีจีสเตอร์ เท่านั้น เพราะฉะนั้นชุดคำสั่ง MIPS จะต้องรวมคำสั่งของการถ่ายโอนข้อมูลระหว่างรีจีสเตอร์และหน่วยความจำ เราเรียกคำสั่งเหล่านี้ว่า คำสั่งถ่ายโอนข้อมูล (Data Transfer Instructions) ในการที่จะเข้าใช้งานไม่ว่าจะอ่านหรือเขียนในหน่วยความจำ คำสั่งถ่ายโอนข้อมูลจะต้องมีแอดเดรสหรือข้อมูลตำแหน่งของหน่วยความจำที่ต้องการใช้งาน เราสามารถพิจารณาให้หน่วยความจำมีลักษณะเป็นอาเรย์มิติเดียวขนาดใหญ่ ที่มีแอดเดรสเป็นตัวระบุตำแหน่งอ้างอิงของอาเรย์ ตัวอย่างเช่นในรูป 2.1 แอดเดรสของข้อมูลตัวที่สาม มีค่าเท่ากับสอง และค่าในแอดเดรสดังกล่าว Memory[2] มีค่าเท่ากับ 10

Figure 2.1: แอดเดรสในหน่วยความจำ และ ข้อมูลที่บรรจุในหน่วยความจำ
\includegraphics[width=3in]{fig/Chapter_2/Figure_2.2.eps}

คำสั่งถ่ายโอนข้อมูลที่ทำหน้าที่คัดลอกข้อมูลที่ต้องการจากหน่วยความจำเข้ามาสู่รีจีสเตอร์ เรียกว่า การโหลด (load) โดยที่รูปแบบของคำสั่งเป็น รีจีสเตอร์ที่จะเป็นที่เก็บข้อมูล และ ตามด้วยเลขจำนวนเต็มที่เป็นค่าคงที่ และรีจีสเตอร์ที่เก็บแอดเดรส หรือตำแหน่งที่ใช้เทียบเคียงในการโหลด ผลบวกของค่าคงที่และค่าแอดเดรสที่อยู่ในรีจีสเตอร์ตัวหลังเป็นค่าของแอดเดรสของข้อมูลที่ทำการโหลด ชื่อของคำสั่ง MIPS คือ ``lw'' ย่อมาจาก load word

การแปลงภาษาเมื่อตัวแปรอยู่ในหน่วยความจำ

กำหนดให้อาเรย์ A ประกอบด้วย 100 Words และ ตัวแปลภาษาหรือคอมไพเลอร์ จะทำการกำหนดคู่ระหว่างตัวแปร g และ h กับรีจีสเตอร์ $s1 และ $s2 และสมมุติให้ base address อยู่ที่ $s3

g = h + A[8];

ในขั้นแรก จะทำการโหลดข้อมูลจากตำแหน่ง 8 ไบต์ห่างจากแอดเดรสที่ระบุไว้ใน $s3 จากนั้นนำค่าของข้อมูลมาเก็บไว้ในรีจีสเตอร์ชั่วคราว $t0 เพื่อทำการบวกกับตัวแปร h ต่อไป

lw $t0, 8 ($s3) # Temporary reg $t0 gets A[8]
add $s1, $s2, $t0 # g = h + A[8]

ค่า 8 เรียกว่าค่า offset ส่วนค่าใน $s3 เรียกว่าค่า Base โดยที่ s3 เรียกว่า Base Register

หน้าที่ของตัวแปลงภาษานอกจากจะต้องทำการกำหนดการใช้งานระหว่างตัวแปรในภาษาระดับสูงแล้ว กับรีจีสเตอร์ต่างๆ แล้ว ยังจะต้องกำหนดค่าเริ่มต้นของแอดเดรสที่ถูกต้อง ให้กับหน่วยความจำ เพื่อให้ได้มาซึ่งการถ่ายโอนข้อมูลที่ถูกต้อง ในทางคอมพิวเตอร์ เราถือว่าข้อมูลขนาด 1 บิตเป็นข้อมูลที่เล็กที่สุด และ 8 บิตมีขนาดเท่ากับ 1 ไบต์ ใน MIPS 4 ไบต์เท่ากับ 1 Wordจากรูป 2.2 แสดงถึงการวางข้อมูลที่เป็น Word ลงในหน่วยความจำ โดยที่ Word แรก อยู่ที่แอดเดรส 0 และ Word ต่อมาอยู่ห่างออกมา 4 ไบต์ ที่แอดเดรส 4 และเรียงกันต่อมาทีละ 4 ไบต์ ใน MIPS กำหนดไว้ว่าการวางข้อมูลในหน่วยความจำจะต้องทำครั้งละ 4 ไบต์ ส่วนใหญ่แล้วโปรเซสเซอร์ต่างๆ จะกำหนด Alignment Restriction นั้นคือการเริ่มต้นของ Word จะต้องเริ่มที่ $0, 4, 8, 12, \ldots$ คอมพิวเตอร์จะทำการแบ่งการใช้งาน Word ออกเป็นสองแบบเรียกว่าค่าย Big Endian และค่าย Little Endian ในค่าย Big Endian แอดเดรสทางซ้ายสุดจะทำการชี้ที่ Word ส่วนในของ Little Endian แอดเดรสทางขวาสุดจะเป็นตัวชี้ที่ Word โปรเซสเซอร์ MIPS อยู่ในค่าย Big Endian

Figure 2.2: การแบ่ง Word สำหรับแอดเดรสในหน่วยความจำ และ ข้อมูลที่บรรจุในหน่วยความจำ
\includegraphics[width=3in]{fig/Chapter_2/Figure_2.3.eps}

คำสั่งที่ตรงข้ามกับ Load คือคำสั่ง Store ที่ทำการคัดลอกถ่ายโอนข้อมูลจากรีจีสเตอร์ ไปบังหน่วยความจำ การใช้งานคำสั่ง Store มีลักษณะคล้ายกับ Load โดยใช้สัญลักษณ์ sw ที่ย่อมาจาก Store Word

การแปลงภาษาที่มีคำสั่ง Load และ Store

สมมุติให้ตัวแปร h อยู่ในรีจีสเตอร์ $s2 และตำแหน่งเริ่มต้นของอาเรย์ A อยู่ที่รีจีสเตอร์ $s3 จงทำการแปลงชุดของภาษา C ดังต่อไปนี้ ให้เป็นภาษาแอสแซมบลีของ MIPS ดังต่อไปนี้

A[12] = h + A[8];

ถึงแม้ว่าภาษา C ข้างบนมีเพียงหนึ่งบรรทัด มีตัวแปรถึงสองตัวอยู่ในหน่วยความจำ เราจึงจำเป็นต้องใช้งานคำสั่ง MIPS มากขึ้นเพื่อสามารถถ่ายโอนตัวแปรจากหน่วยความจำ มาที่รีจีสเตอร์ก่อนทำการประมวลผล ในขั้นแรกทำการเรียกค่าใน A[8] มาที่รีจีสเตอร์ $t0: และทำการบวกค่า $s2 เก็บผลลัพธ์ในรีจีสเตอร์ $t0

lw $t0, 32($s3) # Temporary reg $t0 gets A[8]
add $t0, $s2, $t0 # Temporary reg $t0 gets h + A[8]

จากนั้นทำการเก็บค่านั้น เข้าไปที่หน่วยความจำ A[12] โดยใช้ค่า 48 บวกกับตำแหน่งเริ่มต้นของอาเรย์ A อยู่ที่รีจีสเตอร์ $s3

sw $t0, 48($s3) # Store h + A[8] back into A[12]

การประมวลผลสำหรับตัวแปรที่เป็นค่าคงที่

ในการพัฒนาโปรแกรมนั้น มีการประมวลผลจำนวนมากที่กระทำการกับค่าคงที่ เช่น การเพิ่มค่าดัชนี ในการคำนวณอาเรย์ หรือเมทริกซ์ ในทางเป็นจริง จากการวิเคราะห์ SPEC2000 Benchmarks มากกว่าครึ่งของการประมวลผลทั้งหมดเป็นการคำนวณที่มีค่าคงที่เป็นส่วนหนึ่งของตัวแปร

จากคำสั่งของ MIPS ที่ผ่านมา การใช้งานค่าคงที่จำเป็นต้องใช้สองคำสั่ง โดยคำสั่งแรกทำการเรียกค่าคงที่จากหน่วยความจำ และจากนั้นทำการประมวลผลอีกครั้งหนึ่ง (ค่าคงที่นั้นๆ ต้องถูกเก็บไว้ในหน่วยความจำก่อนหน้า) ตัวอย่างเช่น การบวกค่าคงที่ 4 กับค่าในรีจีสเตอร์ $s3 สามารถใช้คำสั่งดังต่อไปนี้

  
lw $t0, AddrConstant4($s1) # $t0 = constant 4
add $s3, $s3, $t0 # $s3 = $s3 + $t0 ( $t0 == 4)

โดยสมมุติให้ AddrConstant4 เป็นตำแหน่งเก็บหน่วยความจำของค่าคงที่ 4

การทำการถ่ายโอนค่าคงที่จากหน่วยความจำนั้น เป็นการสิ้นเปลืองทรัพยากร เนื่องจากต้องทำการย้ายข้อมูลจากหน่วยตวามจำมายังรีจีสเตอร์หลายครั้ง ในคำสั่ง MIPS จึงมึคำสั่งที่สามารถบวกตัวแปรในรีจีสเตอร์กับค่าคงที่ได้ในคำสั่งเดียว เรียกว่าคำสั่ง ``add immediate'' หรือ addi ในการบวกค่าคงที่ 4 กับค่าในรีจีสเตอร์ $s3 สามารถได้ในคำสั่งดังต่อไปนี้

addi $s3, $s3, 4 # $s3 = $s3 + 4

คำสั่งขั้นต้น เป็นคำสั่งที่นำมาสู่หลักการพื้นฐานในการออกแบบคอมพิวเตอร์ในข้อที่สาม ได้แก่

Design Principle 3: Make the common case fast

ในโปรแกรมจริงพบว่ามีคำสั่งเป็นจำนวนมากที่ดำเนินการประมวลผลระหว่างตัวแปรกับค่าคงที่ การที่มีคำสั่งบวกค่าคงที่กับค่าตัวแปรมนรีจีสเตอร์ในหนึ่งคำสั่งโดยไม่ต้องโหลดข้อมูลจากหน่วยความจำทำให้รวดเร็วกว่ามาก


next up previous contents index
Next: การแสดงคำสั่งในคอมพิวเตอร์ Up: คำสั่ง: ภาษาของคอมพิวเตอร์ Previous: การทำงานของคอมพิวเตอร์ฮาร์ดแวร์   Contents   Index
Vara Varavithya 2006-11-06