ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

使用图形着色的寄存器分配

2021-08-01 10:00:31  阅读:438  来源: 互联网

标签:Node 颜色 idx int 着色 寄存器 图形 节点


COMP26020 -第三部分(编译器)实验练习

使用图形着色的寄存器分配

背景

计算机程序,无论使用哪种编程语言,通常使用的变量比所有CPU寄存器所能容纳的变量数量要多得多。当一个程序在给定的处理器上编译执行时,编译器需要考虑哪些变量将在寄存器中保存以及保存多长时间。如果我们认为从内存中移动数据需要几个周期,那么如果编译器能够最小化这种传输,就会有性能上的好处。怎么做呢?通过做一些“聪明的”寄存器分配,例如,通过确保最常用的变量被放置在寄存器中。

为了理解这个问题,考虑下面的代码:

1.r1 = x

2.r2 = y

3.r3 r2 = r1 *

4.r4 z =

5.r5 = r4 + r2

6.r6 = w

7.r7 = r5 + r6

8.r8 = r7 * r3

9.r9机型= r8 + r1

在这段代码中,程序员使用了9个变量。然而,这是否意味着需要9个寄存器?为了找到答案,让我们定义一个活的范围的概念。对于任何给定的变量,都有一个活动范围,从赋值给该变量的点开始,一直持续到最后一次使用该特定值为止。注意,如果一个新的值被分配给同一个变量,一个新的活动范围开始。例如,指令2中定义了r2的一个值。最后一次使用它是在指令5中,因此,有效值范围在2到5之间。但是,如果指令4是r2=z,则活的范围将从2到3,另一个活的范围将从指令4开始到指令5结束。

为了实践,您可能需要找到上述代码的所有活动范围。给出的答案是:r1: [1, 9], r2:[2、5],r3: [3 8], r4:(4、5),r5:[5、7],r6:[6、7],r7: [7,8], r8:(8、9),r9机型:[9,9]。

活动范围很重要,因为它们指示在任何给定指令中需要有多少个活动值。例如,上面的live范围告诉我们在指令6中有四个值需要是live的。显然,任何指令中需要活的值的最大数目表明我们需要有多少个寄存器,以便所有的值(活的范围)都可以放置在寄存器中。然而,最重要的是,live ranges可以指导寄存器分配:两个不重叠或干扰的live ranges可以使用相同的寄存器。例如,对于上面的live范围,r2和r6可以共享相同的寄存器,因为代码的不同部分需要相应的值(或者是“live”)。已经开发了不同的算法来寻找如何分配不同的活范围到寄存器。这个问题称为寄存器分配。这是一个np完全问题,这意味着多年来提出的大多数不同的解决方案都是基于启发式的。更多信息,你可以在“编译工程”推荐教科书的第13章找到更多:

https://www.sciencedirect.com/science/article/pii/B978012088478000013X

在不同的方法中,使用图着色的寄存器分配是一种常见的方法。在使用图着色的寄存器分配中,活量程被用来创建干扰图。在这个图中,每个活动范围对应一个节点。如果活动范围重叠,两个节点之间有一条边。然后,寄存器分配问题就等价于图着色问题。这是一个著名的图论问题,其目的是给图的所有节点涂上颜色,这样两个相邻的节点就不会有相同的颜色。通常的目标是找到最小数量的颜色。每种颜色都对应一个音域和音域

节点的颜色对应于应用于特定活动范围的寄存器。有各种各样的算法来给图上色。这里,我们将关注一个简单的算法,它被称为自上而下的着色。算法工作原理如下:

1.假设有一个有序的颜色列表(如红、黑、蓝等)

2.设干涉图,节点编号为:1,2,3,…

3.干扰图中的节点(即活动范围)按照邻居数量降序排列。在出现tie的情况下(即邻居数量相同的节点),id最低的节点优先。

4.按照颜色列表中的排序来分配颜色。对于每个节点,从列表中选择第一个未被节点的邻居使用的颜色。

5.继续遵循排名并重复步骤4,直到所有节点都被着色。

你的任务

使用你选择的编程语言来实现一个程序:

读取列出干涉图(输入)的文件。

编写一个文件,列出图形(输出)的每个节点的颜色。

颜色列表是由字母表中的大写字母给出的:A, B, C,…,Z.共有26种颜色(或寄存器)。

输入文件规范:

等于干涉图节点数的线数。每一行都包含节点的编号(按升序排列)以及与之发生干扰的所有节点的编号。例子:

1234

214

31

412

这意味着节点1与节点2、3、4相互干扰。节点2会干扰节点1(我们已经知道了)和节点4。节点3与节点1相互干扰,节点4与节点1、节点2相互干扰。您可以假设不超过50个节点。

输出文件规范:

对于每个节点(升序),写入节点编号和颜色。例如:

1

2 b

3 b

4摄氏度

请确保您遵循的规格,因为大部分标记将自动进行。您的可执行文件应该接受两个参数,它们指示输入文件的名称和输出文件的名称。例如:

myprogram.exe输入。txt输出。txt

你应该能够在两个实验中完成这项任务。报名截止日期为2nd 3 .课程开始前rd 实验室会话。

你应该通过gitlab提交。你的提交应该包括源文件和自述文件,并说明如何编译和运行你的代码。

(满分10分)将按以下方案进行评分:2分代码可读性和合理注释/解释。2正确实现上述示例的标记。正确找到额外的自动测试输出的6分。



#include <bits/stdc++.h>
#include<iostream>
#include<cstring>
#include<fstream>
using namespace std;
const int MAXN = 100;
int n, m = 26;  //n表示结点个数,m表示颜色个数
int a[MAXN][MAXN];  

struct node{
	int idx;
	int cnt;
}Node[MAXN];

void NextValue(int k,int m,int* x)
{
	//在[1,m]中为x[Node[k].idx]确定一个值最小的,且不与其邻接点冲突的颜色
	//x[Node[k].idx]=0表示没有可用的颜色,颜色从1开始进行编号
	int j;
    do{
		x[Node[k].idx]=(x[Node[k].idx]+1) % (m+1);    		 //尝试下一种颜色 
		if(!x[Node[k].idx]) return;         		 //没有可用颜色 
		for(j = 1; j < k; j++)  {
			if(a[Node[k].idx][Node[j].idx] && x[Node[k].idx] == x[Node[j].idx])  //若(i,j)是图的边,且相邻结点k和j颜色相同 
				break;                   //发生冲突,选择下一种颜色 
			}
		if(j == k) return;               //成功选择一种颜色返回 
	}while(1);
}
void mColoring(int k,int m,int *x)
{
	if(k == n+1) {                //得到图G的一种m-着色方案 
		return;
	}
	NextValue(k, m, x);             //为x[Node[k].idx]分配颜色 
	if(!x[Node[k].idx])  return;    //x[Node[k].idx]=0表示当前没有合适的颜色 
	else mColoring(k+1,m,x);         //已经对前k个结点分配了颜色,尝试其余结点 
}

bool cmp(const node &A, const node &B) {
	if(A.cnt > B.cnt) {
		return 1;
	}
	return 0;
}
int main(int argc, char *argv[])      //主函数
{
	ifstream infile(argv[1],ios::in);
 
    if(!infile){  // 判断文件是否存在
      cerr<<"open error."<<endl;
      exit(1); // 退出程序
    }
    char str[255]; // 定义字符数组用来接受读取一行的数据
	n = -1; 
    while(infile)
    {
        infile.getline(str,255);  // getline函数可以读取整行并保存在str数组里
        int idx = str[0]-'0';
        Node[idx].idx = idx;
		Node[idx].cnt = strlen(str)/2;
		for(int i = 2; i < strlen(str); i+=2) {
			int xx = str[i]-'0';
			a[idx][xx] = 1;
		}
		n++;
    }
    sort(Node+1, Node+n+1, cmp);
	
	int *x = new int[MAXN];
    
    for(int i = 1; i <= n; i++) x[i] = 0;
	mColoring(1, m,x);
	freopen(argv[2], "w", stdout);
	for(int i = 1; i <= n; i++) {
		printf("%d%c\n", i,'A'+x[i]-1); 
	} 
 
    return 0;
}
 

标签:Node,颜色,idx,int,着色,寄存器,图形,节点
来源: https://blog.csdn.net/qq_24624539/article/details/119294255

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有