0% found this document useful (0 votes)
4 views19 pages

DSC Report

Uploaded by

nityareddy164
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
4 views19 pages

DSC Report

Uploaded by

nityareddy164
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 19

DEPARTMENT OF COMPUTER SCIENCE AND ENGINEERING

RAMAIAH INSTITUTE OF TECHNOLOGY

Feb 2024

Design and implementation of a queue compiler

TECHNICAL CODETHAN REPORT


SUBMITTED TO

RAMAIAH INSTITUTE OF TECHNOLOGY


(Autonomous Institute, Affiliated to VTU)

Bangalore – 560054

SUBMITTED BY
Joann Mary Joseph 1MS22CS072
P. Nitya Reddy 1MS22CS098
Pranshu Saraswat 1MS22CS105

As part of the Course Data Structures– CS33

SUPERVISED BY
Faculty
Ms. Manjula Raghu

1
Department of Computer Science and Engineering
Ramaiah Institute of Technology
(Autonomous Institute, Affiliated to VTU)

Bangalore – 54

CERTIFICATE

This is to certify that Joann M. Joseph: 1MS22CS072, P.Nitya Reddy: 1MS22CS098 and
Pranshu Saraswat: 1MS22CS105 have completed the “Design and implementation of a queue
compiler” as part of Technical Codethan. We declare that the entire content embodied in this B.E. 3rd
Semester report contents are not copied.

Guided by-
Ms. Manjula Raghu

Submitted by

Name: USN:
Joann M. Joseph 1MS22CS072

P. Nitya Reddy 1MS22CS098

Pranshu Saraswat 1MS22CS107

2
Department of Computer Science and Engineering
Ramaiah Institute of Technology
(Autonomous Institute, Affiliated to VTU)

Bangalore – 54

Evaluation Sheet

Sl USN Name Research Demo & Total


. Content Report Marks
N understand submissio
o ing n (20)
and Coding (10)
(10)
1MS22CS072 JOANN M. JOSEPH

1MS22CS098 P. NITYA REDDY

1MS22CS105 PRANSHU SARASWAT

Evaluated By
Name: Ms. Manjula Raghu
Department: Computer Science & Engineering, RIT
Signature: HOD, CSE

3
Table of Contents

Page No

1. Abstract 5

2. Introduction 6

3. Literature Survey 7

4. Abstract Data Type 8

5. Implementation 10

6. Results and Discussions 16

7. Conclusion 18

8. References 19

4
Chapter 1

Abstract:

1.1 Queue Computational Model-Based Compiler for Instruction Scheduling

• Queue processors are a viable alternative for high performance embedded computing and parallel
processing. We present the design and implementation of a compiler for a queue-based processor.
Instructions of a queue processor implicitly reference their operands making the programs free of false
dependencies. Compiling for a queue machine differs from traditional compilation methods for
register machines. The queue compiler is responsible for scheduling the program in level-order
manner to expose natural parallelism and calculating instructions relative offset values to access their
operands..

The foundation of the compiler lies in the Queue Computational Model, utilizing a queue to manage the
flow of instructions and their dependencies. LDAGs represent the program's structure, where each node
corresponds to an instruction, and edges define their order of execution. Symbolic execution is employed
to track the Queue Head (QH) position, vital for accurate instruction scheduling.

• The heart of the compiler is its instruction scheduling algorithm, which strategically orders
instructions to reduce pipeline stalls and improve overall program performance. Offset calculation
ensures proper memory access, and the final output is optimized assembly code tailored for the target
architecture.

• Users interact with the compiler by providing high-level code, allowing the system to generate
LDAGs, perform symbolic execution, and produce optimized assembly code. The project aims to
deliver improved performance, portability across architectures, and a user-friendly interface for
seamless interaction.

• In conclusion, this project presents an innovative compiler design, leveraging the Queue
Computational Model to enhance instruction scheduling. Through LDAGs, symbolic execution, and
careful algorithmic design, the compiler strives to contribute to the generation of efficient and
optimized machine code, addressing the evolving needs of modern computing environments.

5
Chapter 2
Introduction
2.1 Introduction

• As silicon technology advances, providing ever-increasing levels of integration, current computer


architectures face challenges in fully harnessing the potential of the growing transistor count to deliver
equivalent performance. This limitation has led to the exploration of novel computer architectures
designed to exploit future silicon technologies. Among these emerging architectures, queue computing
stands out as a promising computational scheme for addressing present challenges in microprocessor
design.

2.2 Evaluation:

An evaluation of the queue compiler's performance is presented, assessing its effectiveness in generating
efficient and compact code. This section provides insights into the compiler's capabilities and limitations
based on experimental results.

2.3 Key Components:

2.3.1 Queue Computational Model:


• The foundation of our compiler is the Queue Computational Model, a unique approach to
managing instructions and their dependencies. It involves the use of a queue to represent the
order of computation, allowing for efficient scheduling and execution.
2.3.2 Leveled Directed Acyclic Graphs (LDAGs):
• Our compiler employs Leveled Directed Acyclic Graphs (LDAGs) to represent the
dependencies among instructions. Each node in the LDAG corresponds to an instruction, and
the edges define the order in which instructions should be executed.
2.3.3 Symbolic Execution and QH Positioning:
Symbolic execution is used to track the Queue Head (QH) position relative to each instruction. This
information is vital for efficient scheduling and optimization.
2.3.4 Scheduling Algorithm:
The heart of our compiler lies in its instruction scheduling algorithm. It leverages the LDAGs and QH
positions to arrange instructions in an optimal order, reducing pipeline stalls and enhancing overall
program performance.
2.3.5 Offset Calculation and Assembly Code Generation:
To ensure correct memory access and operand handling, your compiler incorporates offset calculation
based on LDAG information. The final output includes assembly code tailored for the target
architecture.

6
Chapter 3

LITERATURE SURVEY-
3.1 Queue computing overview

Queue computing, distinguished by its reliance on a first-in-first-out (FIFO) queue, offers a unique approach
to expression evaluation.
The proposed infrastructure employs algorithms and data structures to maintain code generation
independence, emphasizing level-order scheduling of programs and instruction offset calculation as unique
features.

3.2 Queue Compiler: Navigating the Unique Landscape of Queue Computation


The development of a compiler for the queue computation model introduces novel methodologies and
challenges distinct from traditional compilers designed for register machines. This comprehensive queue
compiler infrastructure spans five critical phases, incorporating innovative techniques to address the specific
requirements of queue-based computing.

3.2.2 Instruction Selection:

3.2.3 Offset Calculation: Navigating Leveled DAGs

3.2.4 Instruction Scheduling: Embracing Level-Order Topology

3.2.5 Assembly Generation:

3.3 Code Size Analysis: Code size was measured from the object code's text segment, considering the small,
two-byte instructions. Normalized code size results reveal that on average, queue programs exhibit
approximately 30% higher code density compared to fully optimized register machine code. Ongoing work
includes exploring additional classical optimizations to further enhance these results.

3.4 Compile-Time Parallelism: To gauge compile-time parallelism, we maintained the same compiler
configuration and measured the exposed parallelism. On average, the queue compiler, even without ILP
optimizations, demonstrated approximately 7% more parallelism compared to fully optimized register code.
We anticipate that integrating advanced ILP optimizations into the queue compiler could further enhance ILP
extraction, considering the machine-independent nature of these transformations, potentially benefiting queue
programs.
7
Chapter 4

ABSTRACT DATA TYPE


4.1 Queue Abstract Data Type (ADT):

ADT Queue {
data: array or linked list to store elements
capacity: maximum number of elements the queue can hold
size: current number of elements in the queue

operations:
- enqueue(element): Add an element to the rear of the queue
- dequeue(): Remove and return the element from the front of the queue
- front(): Return the element at the front of the queue without removing it
- isEmpty(): Check if the queue is empty
- isFull(): Check if the queue is full
- size(): Return the current size of the queue
}

4.2 Leveled Directed Acyclic Graph Node (LDAGNode) Abstract Data Type (ADT):

ADT LDAGNode {
operation: symbol representing the operation of the node ('+', '*', '/', etc.)
operand: symbol representing the operand or variable ('A', 'B', 'C', etc.)
level: level of the node in the LDAG
qhPosition: position of the Queue Head (QH) relative to the node

left: pointer to the left child node


right: pointer to the right child node
}

4.3 Leveled Directed Acyclic Graph (LDAG) Abstract Data Type (ADT):

8
ADT LDAG {
root: pointer to the root node of the LDAG
operations:
- createNode(operation, operand, level): Create a new LDAG node with the given attributes
- addChild(parent, child): Add a child node to a parent node in the LDAG
- removeNode(node): Remove a node from the LDAG
- traverseLevelOrder(): Traverse the LDAG in level-order fashion
- symbolicExecution(): Perform symbolic execution to track QH positions in the LDAG
- calculateDistance(u, v): Calculate the distance between two nodes in the LDAG
- calculateQHPosition(u): Calculate the QH position relative to a node in the LDAG
- calculateOffsetReference(instruction, operand): Calculate the offset reference value for an
operand
}

9
Chapter 5

IMPLEMENTATION
#include <stdio.h>
#include <stdlib.h>
typedef struct LDAGNode {
char operation; // Operation symbol: '+', '*', '/'
char operand; // Variable symbol: 'A', 'B', 'C', 'D'
int level; // Level of the node in the LDAG
int qhPosition; // QH position relative to the node
struct LDAGNode* left;
struct LDAGNode* right;
} LDAGNode;
typedef struct QueueNode {
LDAGNode* node;
struct QueueNode* next;
} QueueNode;

typedef struct {
QueueNode* front;
QueueNode* rear;
} Queue;
// Function to create a new LDAG node
LDAGNode* createNode(char operation, char operand, int level) {
LDAGNode* newNode = (LDAGNode*)malloc(sizeof(LDAGNode));
newNode->operation = operation;
newNode->operand = operand;
newNode->level = level;
newNode->qhPosition = 0;
newNode->left = NULL;
newNode->right = NULL;
return newNode;
}

Queue* createQueue() {
Queue* queue = (Queue*)malloc(sizeof(Queue));
10
queue->front = NULL;
queue->rear = NULL;
return queue;
}
void printQueueContent(Queue* queue) {
QueueNode* temp = queue->front;
while (temp != NULL) {
printf("%c\t",temp->node->operation);
temp = temp->next;
}
}
void enqueue(Queue* queue, LDAGNode* node) {
QueueNode* newNode = (QueueNode*)malloc(sizeof(QueueNode));
newNode->node = node;
newNode->next = NULL;

if (queue->rear == NULL) {
queue->front = newNode;
queue->rear = newNode;
} else {
queue->rear->next = newNode;
queue->rear = newNode;
}
}
void enqueueInOrder(Queue* queue, LDAGNode* node) {
if (node != NULL) {
enqueueInOrder(queue, node->left);
enqueue(queue, node);
enqueueInOrder(queue, node->right);}}
void symbolicExecution(LDAGNode* root, int qhPosition) {
if (root != NULL) {
// Assign QH position
root->qhPosition = qhPosition;

// Recursively update QH positions for left and right children


symbolicExecution(root->left, qhPosition);
11
symbolicExecution(root->right, qhPosition + 1); // Increment QH position for right child
}
}

int countNodesInLevelOrder(LDAGNode* root) {


if (root == NULL) {
return 0;
}

int count = 0;
int front = 0, rear = 0;
LDAGNode* queue[100]; // Assuming a maximum of 100 nodes in the LDAG

// Enqueue the root


queue[rear++] = root;

while (front < rear) {


LDAGNode* current = queue[front++];

// Process the current node (you can count, print, or perform other operations)
count++;

// Enqueue left child


if (current->left != NULL) {
queue[rear++] = current->left;
}

// Enqueue right child


if (current->right != NULL) {
queue[rear++] = current->right;
}
}

return count;
}

12
int calculateQHPosition(LDAGNode* u) {
return u->qhPosition;
}
// Function to calculate the distance between two nodes in a LDAG
int calculateDistance(LDAGNode* u, LDAGNode* v) {
if (u == NULL || v == NULL) {
return -1; // Invalid input
}

// Initialize a distance array to track the distance from the source node u
int* distanceArray = (int*)malloc(sizeof(int) * 100); // Assuming a maximum of 100 nodes
for (int i = 0; i < 100; i++) {
distanceArray[i] = -1; // Initialize distances to -1 (indicating not visited)
}

// Create a queue for BFS traversal


LDAGNode* queue[100];
int front = 0, rear = 0;

// Enqueue the source node u


queue[rear++] = u;
distanceArray[u->level] = 0; // Distance from u to itself is 0

while (front < rear) {


LDAGNode* current = queue[front++];

// Explore neighbors
if (current->left != NULL && distanceArray[current->left->level] == -1) {
queue[rear++] = current->left;
distanceArray[current->left->level] = distanceArray[current->level] + 1;
}

if (current->right != NULL && distanceArray[current->right->level] == -1) {


queue[rear++] = current->right;
distanceArray[current->right->level] = distanceArray[current->level] + 1;
}
13
}

// Distance between u and v is stored in the distanceArray at the level of v


int distance = distanceArray[v->level] - 1;

// Free allocated memory


free(distanceArray);

return distance;
}

void printLDAGNodeLvl(LDAGNode* node) {


if (node != NULL) {
printLDAGNodeLvl(node->left);
printf("Operation: %c, Variable: %c, Level: %d\n",node->operation, node->operand,node->level);
printLDAGNodeLvl(node->right);}
else{printf(" ");}
}
void printLDAGNodeQH(LDAGNode* node) {
if (node != NULL) {
printLDAGNodeQH(node->left);
printf("Operation: %c, Variable: %c, Level: %d, QH Position: offset- %d\n",node->operation, node-
>operand,node->level, node->qhPosition);
printLDAGNodeQH(node->right);}
else{printf(" ");}
}

int main() {
LDAGNode* root = createNode('/', '\0', 1);
root->left = createNode('+', '\0', 2);
root->left->left = createNode('A', 'A', 3);
root->left->right = createNode('*', '\0', 3);
root->left->right->left = createNode('B', 'B', 4);
root->left->right->right = createNode('C', 'C', 4);
root->right = createNode('D', 'D', 2);
14
printf("Calculating levels-\n");
printLDAGNodeLvl(root);
// Perform level-order traversal and count nodes
int nodeCount = countNodesInLevelOrder(root);
printf("\n");
printf("Number of nodes in LDAG: %d\n\n", nodeCount);

printf("Symbolic execution-calculating ofsets\n");


symbolicExecution(root, 0);
printLDAGNodeQH(root);
printf("\nTo demonstrate the calculation of distance between 2 nodes using (BFS) traversal- A and B\n");
printf("\n\nNode A-");
printf("\nLevel in DAG with QH positions:\n");
printLDAGNodeQH(root->left->left);
printf("\n\nNode B-");
printf("\nLeveled DAG with QH positions:\n");
printLDAGNodeQH(root->left->right->left);
// Call calculateDistance function
int distance = abs(calculateDistance(root->left->left, root->left->right->left));
// Print the calculated distance
printf("\nDistance between nodes A and B: %d\n\n", distance);
// Perform instruction scheduling
printf("\nInstruction Scheduling:\n");
Queue* schedulingQueue = createQueue();
enqueueInOrder(schedulingQueue, root);
printQueueContent(schedulingQueue);
return 0; }

15
Chapter 6
RESULTS

16
DISCUSSIONS-

The Queue Compiler project pioneers a revolutionary approach to code generation tailored for the distinctive
queue computation model, characterized by first-in-first-out (FIFO) queue operations.

1. Offset Calculation: Given the absence of explicit registers, the compiler introduces offset references
for operands. Leveled Directed Acyclic Graphs (LDAGs) efficiently manage data dependencies,
enabling effective offset calculation. The project introduces schemes to handle offset references
exceeding the maximum allowed, ensuring correctness and efficiency.
2. Instruction Scheduling: Operating on LDAGs, the scheduling algorithm generates a linear low-level
intermediate representation (QTL) in level order. Reflecting the nature of the queue computation
model, QTL emphasizes a single operand per instruction, augmented by annotations facilitating
machine-dependent transformations.
3. Performance Evaluation: Code size and instruction-level parallelism (ILP) analyses affirm the
compiler's efficacy. Queue programs exhibit superior code density compared to optimized register
machine code. Despite lacking ILP optimizations, the compiler demonstrates notable parallelism,
hinting at further improvement possibilities through advanced ILP techniques.

Future Implementations :

• The Queue Compiler project lays a formidable foundation, inviting future implementations to refine
functionality, enhance performance, and broaden versatility. Optimization strategies hold promise for
significant code generation improvements.

• Further exploration of Instruction-Level Parallelism (ILP) enhancements stands as a key avenue.


Advanced ILP optimization strategies, encompassing software pipelining, speculation, and data
dependency analysis, could amplify parallelism and runtime performance, offering a compelling area
for future development.

• Language support can be extended beyond the current scope, enhancing the compiler's versatility.
Additional front-ends for diverse programming languages would broaden the user base and encourage
the adoption of the queue computation model across various application domains.

• Future implementations could also consider feedback-driven optimization mechanisms, integrating


runtime profiling and feedback to dynamically adjust optimization strategies. Additionally, parallel
compilation strategies could be explored to expedite the code generation process, improving overall
compiler efficiency, especially for large-scale applications.
17
Chapter 6

CONCLUSION-

The queue compiler adeptly addresses the challenges inherent in code generation for queue-based

architectures, presenting an innovative solution through the construction of a robust data flow graph

representation. Leveraging well-chosen data structures, the compiler efficiently calculates essential conditions

for offset references, ensuring optimal code generation.

The Queue Compiler infrastructure emerges as a pioneering solution for the unique challenges posed by the

queue computation model. Through meticulous phases of AST parsing, instruction selection, offset

calculation, instruction scheduling, and assembly generation, the compiler seamlessly transforms high-level C

language constructs into optimized assembly code for the QueueCore processor. The versatility of the

infrastructure, coupled with its machine-independent design, positions it as a powerful tool for the evolving

landscape of queue-based computing. As the field continues to progress, this compiler stands ready to

contribute to the efficient translation of diverse applications into executable code for queue processors,

unlocking new possibilities in embedded computing.

18
REFERENCES
• [1] B. Abderazek, S. Kawata, M. Sowa, Design and architecture for an embedded 32-bit QueueCore,
Journal of Embedded Computing 2 (2) (2006) 191–205.
• [2] B. Abderazek, T. Yoshinaga, M. Sowa, High-level modeling and FPGA prototyping of produced
order parallel queue processor core, Journal of Supercomputing 38 (1) (2006) 3–15.
• [3] V. Agarwal, M. Hrishikesh, S.W. Keckler, D. Burger, Clock rate versus ipc: the end of the road for
conventional microarchitectures, ACM SIGARCH Computer Architecture News 28 (2) (2000) 248–259.
• [4] A.V. Aho, R. Sethi, J.D. Ullman, Compilers Principles, Addison-Wesley, 1986.
• [5] R. Allen, K. Kennedy, Optimizing Compilers for Modern Architectures, Morgan Kaufman, 2002.
• [6] D. Burger, S.W. Keckler, K.S. McKinley, M. Dahlin, L.K. John, C. Lin, C.R. Moore, J. Burrill, R.
McDonald, W. Yoder, Scaling to the end of silicon with EDGE architectures, IEEE Computer 37 (7)
(2004) 45–55.
• [7] A. Canedo, Code Generation Algorithms for Consumed and Produced Order Queue Machines,
Master’s Thesis, University of Electro-Communications, Tokyo, Japan, September 2006.
• [8] A. Canedo, B. Abderazek, M. Sowa, A new code generation algorithm for 2 offset producer order
queue computation model, Journal of Computer Languages, Systems and Structures 34 (4) (2008)
184–194.
• [9] A. Canedo, B. Abderazek, M. Sowa, A GCC-based compiler for the queue register processor, in:
Proceedings of International Workshop on Modern Science and Technology, Wuhan, China, May
2006, pp. 250–255.

19

You might also like