我使用Hexagon-SDK 3.0编译我的HVX DSP架构示例应用程序。有许多与Hexagon-LLVM
相关的工具可以使用位于以下位置的文件夹:
~/Qualcomm/HEXAGON_Tools/7.2.12/Tools/bin
我写了一个小例子来计算两个数组的乘积,以确保我可以利用HVX
硬件加速。但是,当我使用-S
或-S -emit-llvm
生成程序集时,我找不到任何HVX指令的定义,例如vmem
,vX
等。我的C应用程序暂时在hexagon-sim
上执行,直到我设法找到一种方法在板上运行。
据我所知,我需要在C Intrinsic
中定义我的HVX部分代码,但无法根据自己的需要调整现有示例。如果有人能证明如何完成这一过程,那就太好了。同样在[Hexagon V62 Programmer's Reference Manual][1]
中,许多内在指令都没有定义。
这是我在纯C中的小应用程序:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
#if defined(__hexagon__)
#include "hexagon_standalone.h"
#include "subsys.h"
#endif
#include "io.h"
#include "hvx.cfg.h"
#define KERNEL_SIZE 9
#define Q 8
#define PRECISION (1<<Q)
double vectors_dot_prod2(const double *x, const double *y, int n)
{
double res = 0.0;
int i = 0;
for (; i <= n-4; i+=4)
{
res += (x[i] * y[i] +
x[i+1] * y[i+1] +
x[i+2] * y[i+2] +
x[i+3] * y[i+3]);
}
for (; i < n; i++)
{
res += x[i] * y[i];
}
return res;
}
int main (int argc, char* argv[])
{
int n;
long long start_time, total_cycles;
/* -----------------------------------------------------*/
/* Allocate memory for input/output */
/* -----------------------------------------------------*/
//double *res = memalign(VLEN, 4 *sizeof(double));
const double *x = memalign(VLEN, n *sizeof(double));
const double *y = memalign(VLEN, n *sizeof(double));
if ( *x == NULL || *y == NULL ){
printf("Error: Could not allocate Memory for image\n");
return 1;
}
#if defined(__hexagon__)
subsys_enable();
SIM_ACQUIRE_HVX;
#if LOG2VLEN == 7
SIM_SET_HVX_DOUBLE_MODE;
#endif
#endif
/* -----------------------------------------------------*/
/* Call fuction */
/* -----------------------------------------------------*/
RESET_PMU();
start_time = READ_PCYCLES();
vectors_dot_prod2(x,y,n);
total_cycles = READ_PCYCLES() - start_time;
DUMP_PMU();
printf("Array product of x[i] * y[i] = %f\n",vectors_dot_prod2(x,y,4));
#if defined(__hexagon__)
printf("AppReported (HVX%db-mode): Array product of x[i] * y[i] =%f\n", VLEN, vectors_dot_prod2(x,y,4));
#endif
return 0;
}
我使用hexagon-clang
编译它:
hexagon-clang -v -O2 -mv60 -mhvx-double -DLOG2VLEN=7 -I../../common/include -I../include -DQDSP6SS_PUB_BASE=0xFE200000 -o arrayProd.o -c arrayProd.c
然后将其与subsys.o
(在DSK中找到并已编译)和-lhexagon
链接以生成我的可执行文件:
hexagon-clang -O2 -mv60 -o arrayProd.exe arrayProd.o subsys.o -lhexagon
最后,使用sim:
运行它hexagon-sim -mv60 arrayProd.exe
答案 0 :(得分:1)
有点晚,但可能仍然有用。
Hexagon Vector eXtensions不会自动发出,当前指令集(从8.0 SDK开始)仅支持整数操作,因此编译器不会为包含&#34; double&#34;的C代码发出任何内容。类型(它类似于SSE编程,您必须手动打包xmm寄存器并使用SSE内在函数来执行您需要的操作)。
您需要定义应用程序真正需要的内容。
例如,如果您正在编写与3D相关的内容并且确实需要计算双(或浮点)点积,则可以将yout浮点数转换为16.16定点,然后使用指令(即C内在函数)
Q6_Vw_vmpyio_VwVh
和Q6_Vw_vmpye_VwVuh
模拟定点乘法。
To&#34;启用&#34; HVX你应该使用
中定义的HVX相关类型#include <hexagon_types.h>
#include <hexagon_protos.h>
像vmem&#39;这样的说明和&#39; vmemu&#39;为
之类的语句自动发出// I assume 64-byte mode, no `-mhvx-double`. For 128-byte mode use 32 int array
int values[16] = { 1, 2, 3, ..... };
/* The following line compiles to
{
r4 = __address_of_values
v1 = vmem(r4 + #0)
}
You can get the exact code by using '-S' switch, as you already do
*/
HVX_Vector v = *(HVX_Vector*)values;
你的(定点)版本的dot_product可以一次读出16个整数,乘以几个指令中的所有16个整数(参见HVX62编程手册,有一个提示从16-实现32位整数乘法第一), 然后shuffle / deal / ror数据并总结重新排列的向量以获得点积(这样你几乎可以同时计算4个点产品,如果你预加载4个HVX寄存器 - 即16个4D向量 - 你可以计算16个点产品平行)。
如果你正在做的只是字节/ int图像处理,你可以在Hexagon指令集中使用特定的16位和8位硬件点产品,而不是模仿double
和{{1} }第