使用值而不是指针作为函数参数

using values instead of pointers as function arguments

我有这个函数 "cost_compare",出于某些实验目的,我想将其卸载到 FPGA 上。这个函数,它是如何被调用的,它的参数如下。

综合工具不接受双指针作为硬件函数的参数(事实上,它非常挑剔地使用指针,尤其是对数据结构)。

如何去掉函数参数列表中的指针?换句话说,如何将此示例中的指针转换为值?这种可能的解决方案如何影响 spec_qsort 执行的引用调用?

提前致谢 胡曼

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' 时,它仅适用于

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',我相信这个问题可以用硬件综合工具解决.

亲切的问候 胡曼

int cost_compare( BASKET **b1, BASKET **b2 ) 中你不需要双指针,因为你只是比较元素而不是交换任何东西。 (实际上请注意,您没有直接使用 b1,而是总是取消引用它)

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

此外,由于 spec_qsort 需要一个带有签名 int compare (void *, void *) 的函数,您可以去掉这个强制转换 "(int (*)(const void *, const void *)) cost_compare)" ,将 cost_compare 的签名更改为适当的签名并将参数转换为函数内部,如下所示:

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),这样一切都更容易阅读。

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

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;
    }

既然cost_compare函数只是比较abs_cost和id,为什么不直接传递,像这样。

int cost_compare(cost_t abs_cost1, int id1, cost_t abs_cost2, int id2)
{
    if( abs_cost1 < abs_cost2 )
        return 1;
    if( abs_cost1 > abs_cost2 )
        return -1;
    if( id1 > id2 )
        return 1;
    else
        return -1;
}

然后你这样称呼它。

const_compare(act->abs_cost, act->a->id, max->abs_cost, max->a->id)