【问题标题】:Using System.arraycopy in Java在 Java 中使用 System.arraycopy
【发布时间】:2012-03-23 19:12:51
【问题描述】:

所以我创建了一个直接映射的回写缓存模拟器。

在测试我的东西时,我写了地址 0x14c 值“99”,它原本是一个值“4C” 然后我读入值0x348,这使得回写功能发生,因为下面的两个地址都指向相同的插槽号,只是不同的标签。

基本上,然后我需要将插槽中的所有数据从“缓存”对象写入 main_mem 对象。我使用 System.array 副本。

我可以看到值 99 已成功写回主内存阵列。

但是当我想再次读取地址 14C 时(应该拉出包括 99 在内的整个块),它会打印最初的内容,而不是反映我写的更改。

System.arraycopy 不会从特定索引开始的数组中提取数据吗?它只是从第一个索引的值开始计算吗?

这是我的 read() 和 write() 方法以及输出

      public static void readAddress() {
          System.out.println("What address? ");

          address = keyboard.nextInt(16);
          startAddress = address & 0x758;
          tag = (address >> 6) & 0x1F;
          slot = (address >> 3) & 0x7;

          //Valid bit is 0, empty slot
          if (cache[slot].getValidBit() == 0) {              

              cache[slot].setValidBit(1);
              cache[slot].setTag(tag);
              cache[slot].setStartAddress(startAddress);

              System.arraycopy(main_Mem, main_Mem[startAddress], cache[slot].dataBlock, 0, cacheSize);

              System.out.println("Cache Miss");
              System.out.print("The value at that address is: ");
              System.out.printf("%X", 0xFF & address);
              System.out.println();
              System.out.println();
          }
          //Valid bit 1 but tags don't match
          else if (cache[slot].getValidBit() == 1 && cache[slot].getTag() != tag) {
              System.out.println("Cache Miss ");

              if (cache[slot].getDirty() == 1) {
                  System.out.println("This is a dirty slot!");
                  //copy contents of slot back into main memory before loading new block
                  System.out.println("Slot is dirty and will be written back, val for 14c is " +cache[slot].dataBlock[4]);
                  System.arraycopy(main_Mem, cache[slot].getStartAddress(), cache[slot].dataBlock, 0, cacheSize);
                  System.out.println("Everything should have been copied to main by now. The value for 332 is " + main_Mem[332]);
              }

              startAddress = address & 0x7F8;
              cache[slot].setTag(tag);
              cache[slot].setStartAddress(startAddress);
              //set dirty back to 0, incase it was 1
              cache[slot].setDirty(0);

              for (int i = 0; i < cacheSize; i++) {
                  for (int j = cache[slot].getStartAddress(); j<cacheSize; j ++) {
                      cache[slot].dataBlock[i] = main_Mem[j];
                  }
              }
              //System.arraycopy(main_Mem, main_Mem[startAddress], cache[slot].dataBlock, 0, cacheSize);
              System.out.print("The value at that address is: ");
              System.out.printf("%X", 0xFF & address);
              System.out.println();
              System.out.println();
          }
          //Valid bit 1 and tags match, hit
          else if (cache[slot].getValidBit() == 1 && tag == cache[slot].getTag()) {
              System.out.println("Cache Hit");
              System.out.print("The value at that address is: ");
              System.out.printf("%X", 0xFF & address);
              System.out.println();
              System.out.println();
          }

          menu();
  }

  public static void writeAddress() {

        System.out.println("What address do you want to write to? ");
        address = keyboard.nextInt(16);
        System.out.println("And what value do you want to write to it? ");
        int input = keyboard.nextInt(16);

        startAddress = address & 0x758;
        tag = (address >> 6) & 0x1F;
        slot = (address >> 3) & 0x7;
        //Valid bit 1, tag matches, hit, just modify value
        if (cache[slot].getValidBit() != 0 && cache[slot].getTag() == tag) {
            System.out.println("Cache Hit");
            System.out.printf("%X", 0xFF & address);

            for (int i = 0; i <8; i++) {
                if (cache[slot].dataBlock[i] == (0xFF & address)) {
                    cache[slot].dataBlock[i] = input;
                    cache[slot].setDirty(1);
                }
            }   
        }
        //Valid bit 1, tags don't match-Check dirty bit and write back first if valid
        else if (cache[slot].getValidBit() == 1 && cache[slot].getTag() != tag) { 

            if (cache[slot].getDirty() ==1) {
                //copy contents of slot back into main memory before loading new block
                for (int i = 0; i < cacheSize; i++) {
                  for (int j = startAddress; j<cacheSize; j++) {
                      cache[slot].dataBlock[i] = main_Mem[j];
                  }
                }
                //System.arraycopy(cache[slot].dataBlock, 0, main_Mem, cache[slot].getStartAddress(), cacheSize);
            }

            System.out.println("Cache Miss");
            cache[slot].setValidBit(1);
            cache[slot].setTag(tag);
            cache[slot].setDirty(1);
            cache[slot].setStartAddress(startAddress);
            //copy new block into cache now
            System.arraycopy(main_Mem, main_Mem[startAddress], cache[slot].dataBlock, 0, cacheSize);

            for (int i = 0; i <8; i++) {
                if (cache[slot].dataBlock[i] == (0xFF & address)) {
                    System.out.println("Writing over the value of that address now...");
                    cache[slot].dataBlock[i] = input;
                }
            }

        }
        //Empty slot, no need to write back
        else if (cache[slot].getValidBit() == 0) {
            System.out.println("Cache Miss");
            System.out.println("Setting the dirty bit to 1");
            System.out.println("Dirty bit was " + cache[slot].getDirty());

            cache[slot].setValidBit(1);
            cache[slot].setTag(tag);
            cache[slot].setDirty(1);
            System.out.println("And is now " +cache[slot].getDirty());
            cache[slot].setStartAddress(startAddress);
            //copy from main mem to cache
            System.arraycopy(main_Mem, main_Mem[startAddress], cache[slot].dataBlock, 0, cacheSize);

            //writes to selected value in the cache
            for (int i = 0; i <8; i++) {
                if (cache[slot].dataBlock[i] == (0xFF & address)) {
                    System.out.println("Writing over the value of that address now...");
                    cache[slot].dataBlock[i] = input;
                }
            }
        }
        menu();
  }

输出:

This is a cache simulator, type in what you want to do and press enter 

[r] to read   [w] to write   [d] to display
w
What address do you want to write to? 
14c
And what value do you want to write to it? 
99
Cache Miss
Setting the dirty bit to 1
Dirty bit was 0
And is now 1
Writing over the value of that address now...
This is a cache simulator, type in what you want to do and press enter 

[r] to read   [w] to write   [d] to display
r
What address? 
348
Cache Miss 
This is a dirty slot!
Slot is dirty and will be written back, val for 14c is 153
Everything should have been copied to main by now. The value for 332 is 76
The value at that address is: 48

This is a cache simulator, type in what you want to do and press enter 

[r] to read   [w] to write   [d] to display

【问题讨论】:

  • 你的问题不是很清楚,但是一个简短但完整的程序演示了这个问题会很容易回答,我敢肯定......
  • "This is a dirty slot!"...一个元音远离热闹!
  • 对不起。我正在将数据从一个数组复制到另一个数组,当我尝试将该数据重新加载回原始数组时,这是不正确的。

标签: java arrays copy


【解决方案1】:

如果 startAddress 是 main_Mem 中的地址,我想你想要:

System.arraycopy(main_Mem, startAddress, ...) 

没有

System.arraycopy(main_Mem, main_Mem[startAddress], ...)

不过,其中一次运行的完整输出可能会更清楚地说明出了什么问题以及原因。

【讨论】:

  • 我更新了我的问题以完全包含我的读写方法。问题是它说“332 的值是 76”。它应该是 153 (0x99)。我的副本并没有按应有的方式保存到主内存中。
  • 问题是第二次读取14c地址(索引)。它不再携带 99. 输出为 4c(就像程序初始化时一样。)
  • :) 我做到了。直到不久前才回复或接受它。现在开心吗?
猜你喜欢
  • 1970-01-01
  • 2011-02-15
  • 2015-06-06
  • 2015-11-16
  • 2019-11-02
  • 1970-01-01
  • 2016-05-19
  • 1970-01-01
  • 2022-01-20
相关资源
最近更新 更多