1

我正在尝试编写一个例程,该例程将以最有效的方式将向量的所有元素向右移动 n 个位置,以适用于以下向量类型:BYTE->BYTE、WORD->WORD、DWORD->DWORD 和WORD->BYTE(假设结果中只有 8 位)。我想根据处理器的类型为每种类型设置三个例程(支持 SSE2,仅支持 MMX,仅支持标准指令 se)。因此我总共需要 12 个函数。

我自己已经找到了如何备份和恢复我需要的寄存器,如何进行循环,如何将数据复制到常规寄存器或 MMX 寄存器以及如何在逻辑上移位 1 个位置。

因为我不熟悉它的汇编语言。我应该为每个指令集使用哪些寄存器?如何优化 L1 缓存中大矢量(图像)的可用性?我如何找到向量的下一个元素(指针之类的东西),我知道我可以按地址制作一个 mov,并且我假设我必须根据我的数据类型将地址增加 1、2 或 4?

虽然我有所有的想法,但在这一点上编写代码有点困难。

谢谢你。

阿尔诺。

编辑:这是我试图为 MMX 在 DWORD 上移动 1 所做的事情:

__asm("push mm"); // backup register
__asm("push cx"); // backup register
__asm("mov %cx, length"); // initialize loop
__asm("loopstart_shift1:"); // start label
__asm("movd %xmm0, r/m32"); // get 32 bits data
__asm("psrlq %xmm0, 1"); // right shift 32 bits data logically (stuffs 0 on the left) by 1
__asm("mov r/m32,%xmm0"); // set 32 bits data
__asm("dec %cx"); // decrement index
__asm("cmp %cx,0");
__asm("jnz loopstart_shift1");
__asm("pop cx"); // restore register
__asm("pop mm"); // restore register
__asm("emms"); // leave MMX state
4

2 回答 2

1

我强烈建议你暂停一下,看看在 C 或 C++ 中使用内部函数,而不是尝试编写原始 asm - 这样 C/C++ 编译器将处理所有寄存器分配、指令调度和一般内务管理任务,你可以专注于重要部分,例如,而不是使用psrlqsee _m_psrlqin mmintrin.h。(更好的是,看看使用 128 位 SSE 内在函数。)

于 2011-06-24T10:32:08.853 回答
0

听起来您会从使用或查看BitMagic的源代码中受益。它也完全基于内在函数,这使得它更具可移植性(尽管从它的外观来看,您使用的是 GCC,因此它可能必须获得 MSVC 到 GCC 内在函数的映射)。

于 2011-06-24T13:07:10.607 回答