使用值代替指针作为函数参数 [英] using values instead of pointers as function arguments

查看:172
本文介绍了使用值代替指针作为函数参数的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我具有此功能"cost_compare",出于某些实验目的,我希望在FPGA上分担此功能.该函数,其调用方式及其参数如下.

I have this function "cost_compare" that I would like to offload on FPGA for some experimental purposes. This function, how it is called and its arguments are as follows.

综合工具不接受双指针作为HW函数的参数(实际上,对于使用指针尤其是针对数据结构,它非常挑剔).

The synthesis tool doesn't accept double pointers as arguments for HW functions (in fact it is very picky about using pointers especially to data structures).

如何摆脱函数自变量列表中的指针?换句话说,如何将本例中的指针转换为值?这种可能的解决方案如何影响spec_qsort通过引用进行的调用?

How do I get rid of the pointers in the function argument list? In other words, how do I convert pointers in this example to values? How does this possible solution affect the call by reference performed by spec_qsort?

先谢谢了 霍曼(Hooman)

Thanks in advance Hooman

typedef struct arc *arc_p;
typedef LONG cost_t;

typedef struct basket
{
    arc_t *a;
    cost_t cost;
    cost_t abs_cost;
    LONG number;
} BASKET;
/* ... */
typedef struct arc
{
    int id;
    cost_t cost;
    node_p tail, head;
    short ident;
    arc_p nextout, nextin;
    flow_t flow;
    cost_t org_cost;
} arc;
/* ... */
extern int cost_compare( BASKET **b1, BASKET **b2 );
/* ... */
int cost_compare( BASKET **b1, BASKET **b2 )
{
    if( (*b1)->abs_cost < (*b2)->abs_cost )
        return 1;
    if( (*b1)->abs_cost > (*b2)->abs_cost )
        return -1;
    if( (*b1)->a->id > (*b2)->a->id )
        return 1;
    else
        return -1;
}
/* ... */
spec_qsort(perm + 1, basket_sizes[thread], sizeof(BASKET*),
           (int (*)(const void *, const void *))cost_compare);
/* ... */
BASKET* max, *act;
for (j = 1; j < num_threads; j++) {
    act = *perm_p[j];
    if (act->number >= 0) {
        if (!max || cost_compare(&act, &max) < 0) {
            max = act;
            max_pos = j;
        }
    }
    /* ... */
    BASKET*     max_basket;
    static BASKET    **opt_basket;

    for (i = 0; i< num_threads; i++) {
        if ((!max_basket && opt_basket[i]) || (opt_basket[i] && 
                                               cost_compare(&opt_basket[i], &max_basket) < 0)) {
            max_basket = opt_basket[i];
        }
    }
/* ... */

=======================================

=========================================

感谢@Gerardo Zinno.当我在SW中运行时,您的方法(在上一段中)工作正常.但是,当我使用Xilinx SDSoC在FPGA上综合"cost_compare"时,它仅适用于

Thanks @Gerardo Zinno. When I run in SW, your approach (in the last paragraph) works fine. However, when I synthesis 'cost_compare' on FPGA using Xilinx SDSoC, it only works for

if(b1->abs_cost < b2->abs_cost)

但不是

if( b1->a->id > b2->a->id )

工具会给我这个错误:

ERROR: [SYNCHK 200-61] /home/a1083898/Xilinx_examples/original_routeplanning/src/pbeampp.c:85: unsupported memory access on variable 'x' which is (or contains) an array with unknown size at compile time.

ERROR: [SYNCHK 200-41] /home/a1083898/Xilinx_examples/original_routeplanning/src/pbeampp.c:89: unsupported pointer reinterpretation from type 'i8*' to type '%struct.arc.1.4.6 = type { i32, i64, %struct.node.0.3.5*, %s...' on variable 'x'.

ERROR: [SYNCHK 200-11] /home/a1083898/Xilinx_examples/original_routeplanning/src/pbeampp.c:89: Argument 'x' has an unsynthesizable type 'i8*' (possible cause(s): pointer to pointer or global pointer).

ERROR: [SYNCHK 200-11] /home/a1083898/Xilinx_examples/original_routeplanning/src/pbeampp.c:89: Argument 'x' has an unsynthesizable type 'i8*' (possible cause(s): structure variable cannot be decomposed due to (1) unsupported type conversion; (2) memory copy operation; (3) function pointer used in struct; (4) unsupported pointer comparison).'

当被"qsort"以

qsort(perm + 1, basket_sizes[thread], sizeof(BASKET*), cost_compare); 

我收到此警告:

warning: incompatible pointer types passing 'int (void *, void *)' to parameter of type '__compar_fn_t' (aka 'int (*)(const void *, const void *)') [-Wincompatible-pointer-types]

我知道此错误与C编程无关,但是如果有任何方法可以摆脱'b1-> a-> id'和'b2-> a-> id',我相信问题可能是用硬件综合工具解决了.

I know this error has nothing to do with C programming but if there is any way to get rid of 'b1->a->id' and 'b2->a->id', I believe the problem could be solved with the HW synthesis tool.

亲切的问候 霍曼

推荐答案

int cost_compare( BASKET **b1, BASKET **b2 )中,您不需要双指针,因为您只是在比较元素而不交换任何内容. (实际上,请注意,您并不是直接使用b1,而是始终取消引用它)

In the int cost_compare( BASKET **b1, BASKET **b2 ) you don't need double pointers since you are just comparing elements and not swapping anything. (In fact notice that you aren't using b1 directly, but you're always dereferencing it)

只需将功能签名更改为int cost_compare( BASKET *b1, BASKET *b2 ).在函数的主体中,将每个(*b1)->abs_const更改为b1->abs_const.

Just change the function signature to int cost_compare( BASKET *b1, BASKET *b2 ). In the function's body change every (*b1)->abs_const to b1->abs_const.

此外,由于spec_qsort需要具有签名int compare (void *, void *)的函数,因此您可以摆脱这种强制转换(int(*)(const void *,const void *))cost_compare)",更改cost_compare的签名转换为合适的参数,然后将参数转换为函数内部的值,如下所示:

Also, since spec_qsort expects a function with signature int compare (void *, void *), you could get rid of this cast "(int (*)(const void *, const void *)) cost_compare)" , change the signature of cost_compare to an appropriate one and cast the arguments inside the function, like this:

int cost_compare( void *a, void *b ){
 BASKET *b1 = a;
 BASKET *b2 = b;
 if(b1->abs_cost < b2->abs_cost){
   return 1;
 }
 ...
 else return -1;
}

然后调用spec_qsort(perm + 1, basket_sizes[thread], sizeof(BASKET*), cost_compare),这样,所有内容都更易于阅读.

and then call spec_qsort(perm + 1, basket_sizes[thread], sizeof(BASKET*), cost_compare), in this way everything is easier to read.

要回答您上一次编辑的内容,请将cost_compare更改为:

To answer to one point of the last edit you made, change cost_compare to :

int cost_compare( const void *a, const void *b ){
     BASKET b1 = *(BASKET *)a;
     BASKET b2 = *(BASKET *)b;
     if(b1.abs_cost < b2.abs_cost){
       return 1;
     }
     ...
     if(*(b1.a).id > *(b2.a).id)
         return 1;
     else return -1;
    }

这篇关于使用值代替指针作为函数参数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆