Golang中的Sized Data Load(将uint16放入uint8切片)



我正在拼凑一个处理器的粗略ISS,我想知道是否有更有效的方法来完成我正在做的事情(理想情况下不使用不安全的库)。(简化)我用表示内存

type DataMem []uint8

注册人:

type Register uint16

内存需要以字节大小为单位,处理器以更大的单位工作,如上所述。这意味着存储我们所做的数据:

func (m *Machine) ExecuteST (ins Instruction) {
  // Store to memory
  // Data to store specified in one register
  // Address to store to specified by another register
  target_address := m.RegBank[ins.Dst]
  src_data := m.RegBank[ins.Src]
  ///////// Start of annoying section////////
  var target_0 uint8
  var target_1 uint8
  target_0 =  src_data & 0x0f
  target_1 = (src_data & 0xf0)>>8
  m.data_mem[target_address  ] = target_0
  m.data_mem[target_address+1] = target_1
  /////////// End of annoying section /////////
  m.logger.Printf("ST To Address %x, Data %xn",target_address,src_data)
}

对于各种不同的数据类型和传输,等等。

让我讨厌的是,我知道go代码将在其上运行的处理器将有一条加载指令,可以在一次传输中完成上述所有操作。我希望一个好的c编译器能为我优化到这一点,但如果不打破不安全的库并直接指向指针,我认为我无法绕过这一点?

我愿意接受一些建议,包括更好的数据内存建模方法。。。

由于Go的类型安全性,在不使用不安全包的情况下,没有什么不同的做法。

最简单的解决方案,可能也是最具性能的解决方案是对目标地址进行转换:

// convert the target address to *uint16
srcData = uint16(0xeeee)
*(*uint16)(unsafe.Pointer(&dataMem[targetAddress])) = srcData

类似地,另一个选项是用指向同一存储器区域的[]uint16片来遮蔽[]uint8片。这看起来更多毛,你必须自己检查你的偏移和对齐。

dataMem16 := (*(*[1<<30 - 1]uint16)(unsafe.Pointer(&dataMem[0])))[:len(dataMem)/2 : len(dataMem)/2]
dataMem16[targetAddress/2] = srcData

另一个尝试的选项是使用内置的copy来移动字节。由于复制是由编译器在汇编中实现的,它可能会做你想做的事情(尽管我还没有检查转换的汇编实际产生了什么,所以它可能是一个清洗)

copy(dataMem[targetAddress:], (*(*[2]uint8)(unsafe.Pointer(&srcData)))[:])

或者作为@OneOfOne显示的内联函数:

func regToMem(reg uint16) *[2]uint8 {
    return (*[2]uint8)(unsafe.Pointer(&reg))
}
copy(mem[targetAddress:], regToMem(0xffff)[:])

https://play.golang.org/p/0c1UywVuzj

如果性能至关重要,并且您希望使用特定于体系结构的指令,那么"正确"的方法是直接在程序集中实现您想要的东西,但从第一个解决方案生成的代码可能很难被击败。

由于我关心的是模拟的效率,另一种选择是以不同的方式声明数据内存,例如

type DataMem []uint32

提供了一种给定地址的方法,该方法排除了字节

func (dm *DataMem) StoreB (address int) uint8 {...}
func (dm *DataMem) Store16 (address int) uint16 {...}

考虑到这是在PC上运行的,那里会有一个数据缓存,所以在现代处理器上获取过大的数据字不会花费任何费用。

我需要一个新的基本规则,当你有棘手的问题时,看看数据结构和你的平台;-)

最新更新