ARTS计划第一周

很高兴能和大家一起实践ARTS的练习。

我结合自己的特点,打算对ARTS的内容做一点调整。因为我本身英语还可以,但是编程的基础较为薄弱。我打算将Review环节换成对我学习《深入理解计算机系统》一书的每周回顾(目前还停留在第三章)。同时将Share环节换成Summary,正好最近有买《计算机体系结构》的英文原版书,计划每周读一小节,可能是2-5页不等,然后写一个摘要。

Algorithm部分

本周完成的是Integer-to-Roman,使用C语言。

  1. 先将1~3999之间的任一整数依次抽出个位到千位的数字,装进一个数组,再用一个变量记住数组长度

  2. 考虑到千位的数字可能为0(无需操作),或为1~3,只有三种可能,因此单独用if先行处理

  3. 百十个位则用了一个至多循环3次的循环,循环中用if-else判断是否是需要特殊处理的4或9,如果没有则以5分界,对照预先保存的罗马数字数组,以数值作为索引提取罗马数字放进全局变量中

  4. 使用cursor记录这个全局变量装载的位置,最后返回这个全局变量

  5. 需要注意的一点就是,因为使用的时全局变量,在实际测试时每调用一次这个函数,需要先清空全局变量,因此造成了额外的开销,仍然有改进的空间。

char roman[16] = {0};

char* intToRoman(int num) {
    // clear roman array
    for(int len = 0; len < 16; len++)
    {
        roman[len]=0;
    }
    
    int digits[4]={0};
    char roman_letters[7]={'I','V','X','L','C','D','M'};
    int i = 0;
    while(num>0)
    {
        digits[i]=num%10;
        i++;
        num /= 10;
    }
    
    int j = i-1;    
    
    int cursor = 0;
    
    if(j==3)
    {
        while(cursor<digits[j])
        {
           roman[cursor]='M';
           cursor++;
        }
        j--;
    }    
    
    while (j>= 0)
    {
        char a = roman_letters[0+j*2];
        char b = roman_letters[1+j*2];
        char c = roman_letters[2+j*2];
        
        int key = digits[j];
        
        int residue = key % 5;
        if (key == 0)
        {
            ;  
        } else if( residue == 4)
        {
            roman[cursor++] = a;
            roman[cursor++] = key>5?c:b;
        } else if ( residue == 0)
        {
            roman[cursor++] = b;
        } else 
        {
            if(key > 5)
            {
                roman[cursor++]=b;
            }
            for(int k = 0 ; k < residue; k++)
            {
                roman[cursor++]=a;
            }
        }
        
        j--;
    }
    
    return roman;
}
复制代码

Review部分

这一周还在看第三章程序的机器级表示,还在啃汇编。对于32位系统,理解了8个整数寄存器的使用,了解了程序是怎么在底层汇编代码中区分无符号整型和补码表示的有符号整数(用sarl和shrl区分移位运算,一个是算术右移补符号位,一个是逻辑右移补0)。或者在使用条件码时,对无符号整型数据,使用进位标志和符号标志判断是否有溢出,对补码符号数使用符号标志和溢出标志判断是否溢出。书里还提到有关跳转指令的地址计算问题,是跳转指令的下一个指令的地址加上跳转指令的操作数,就能够获取要跳往的地址了。

现在看到了第三章后面讲控制代码的汇编实现。IF-ELSE分支在编译成汇编代码时,会首先测试ELSE分支是否成立,为真就直接跳转,否则就执行IF后面的语句。DO-WHILE结构与汇编结构最为对应。WHILE结构则是在DO-WHILE结构前先加一个IF分支判断条件是否成立,不成立就直接结束,成立则完全类似DO-WHILE先执行一次。FOR循环,是在WHILE的基础上,前面添加一个初始化循环变量的语句即可。这几种结构相互递进,书里讲得非常清晰。而且还特别提到了如果循环中有continue语句时,FOR循环的汇编和WHILE循环的汇编是不能完全对应上的,需要在汇编语言里将循环变量更新语句放在continue前。SWITCH语句的检测值被转为无符号数处理。

Tip部分

其实来自上面的书(《深入理解计算机系统》)。对于机器码,使用objdump -d获取反汇编的结果,或是对源代码使用gcc -O1 -S获取编译后的结果。(第三章后面有一节专门讲GDB调试的,暂时还没有看到,后续可以继续补充)

Summary部分

刚刚开始看《计算机体系结构》第一章,1.1节只是简短介绍了计算机软硬件能力在65年来的发展,随着计算机各方面设计的进步和标准化,计算机造价越来越低,也越来越普及。1.2节则是介绍了几种现有市场上常见的计算机分类,移动设备,台式机,服务器,集群式计算机,嵌入式计算机。每种设备各自的特点,如移动设备要求造价低能效高,面向媒体和网络;台式机要求性价比;服务器要求稳定和速度;集群式计算机要求availability(差不多等价于稳定,因为宕机会带来严重的经济损失);嵌入式设备则要求在完成既定功能的基础上使用的硬件越便宜越好。1.2最后一小节还提到了并行和并行结构的分类,数据层面的并行,如GPU和向量架构等(其实我理解就像批处理一样,似乎和MapReduce算法有关,但是也不是很懂),以及任务层面的并行,也还是需要指令层面的并行和线程级的并行。不过至于这些是如何实现的,就还需要继续啃下去了。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值