使用值而不是指针作为函数参数
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)
我有这个函数 "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)