bespoke-silicon-group / bsg_manycore

Tile based architecture designed for computing efficiency, scalability and generality
Other
221 stars 58 forks source link

bsg_printf issue #637

Closed natewise closed 2 years ago

natewise commented 2 years ago

So I have a simple program with this main function:

int main() {
  bsg_set_tile_x_y();

  int id = bsg_x_y_to_id(bsg_x, bsg_y);

  if( (bsg_x < bsg_tiles_X) && (bsg_y < bsg_tiles_Y) ) {
    bsg_printf("[MAIN] x,y=%d,%d id=%d Do stage %d..\n", bsg_x, bsg_y, id, bsg_x);
    bsg_finish();
  }
  bsg_wait_while(1);
}

I'm using the pod_1x1_4X2Y machine with x,y=4,1. I've also set NUM_FINISH = $(shell expr $(bsg_tiles_X) \* $(bsg_tiles_Y) ) in my Makefile to get each tile to send it's own finish packet. The output gives the right information but it's all jumbled together in a confusing manner:

[INFO][RX] Unfreezing tile t=8691000, x=  4, y=  2
[INFO][RX] Unfreezing tile t=8693000, x=  5, y=  2
[INFO][RX] Unfreezing tile t=8695000, x=  6, y=  2
[INFO][RX] Unfreezing tile t=8697000, x=  7, y=  2
[MAIN] x,y=0,0 id=0 Do stage 0..
[MAIN] [INFO][MONITOR] RECEIVED a finish packet from tile y,x= 2, 4, data=00000000, sim_time=11838000, wall_time=21466.23
x,y=1,0 id=1 Do stage 1..
[MAI[INFO][MONITOR] RECEIVED a finish packet from tile y,x= 2, 5, data=00000001, sim_time=12080000, wall_time=21468.25
N] x,y=2,0 id=2 Do stage 2..
[M[INFO][MONITOR] RECEIVED a finish packet from tile y,x= 2, 6, data=00000002, sim_time=12337000, wall_time=21470.21
AIN] x,y=3,0 id=3 Do stage 3..
[INFO][MONITOR] RECEIVED a finish packet from tile y,x= 2, 7, data=00000003, sim_time=12600000, wall_time=21472.13
[INFO][MONITOR] RECEIVED BSG_FINISH PACKET from all pods, time=12601000
- /mnt/c/Projects/bsg_manycore/testbenches/common/v/bsg_nonsynth_manycore_monitor.v:83: Verilog $finish
Finishing test
Executing final
Exiting
rm main.nbf

It looks like there might be some issue with bsg_printf when the system tries to print things at the same time. Any tips or workarounds would be appreciated

drichmond commented 2 years ago

Hi @natewise

Yes, this is expected, but there are workarounds. The reason is that the testbench displays each character from printf as it is received on the network, and it takes multiple simulation cycles, while the INFO messages are printed by the testbench/OS to completion instantaneously.

One workaround is to have all of the tiles synchronize before finishing. This means that the INFO statements will not run until all printfs are complete. That will help this specific case here. It may not generalize well to more complex scenarios.

Another alternative (one I've used) is to use bsg_print_hexadecimal to send a 32-bit value to the host and encode the same information that you're sending via bsg_printf. This is a single packet, which means it won't get spilt by the INFO statements. It ALSO works better for tracking progress in timing critical code without the (substantial) overhead of printf -- which is not your use case here, but hopefully will be in the long run

tommydcjung commented 2 years ago

Another solution is to grab the same lock at the host interface that bsg_printf uses before sending the finish pkt

drichmond commented 2 years ago

That's a good one, too.

natewise commented 2 years ago

I implemented the synchronization tactic used in the bsg_transpose example using bsg_barrier, and it worked great. Thanks for the others suggestions, I may need them potentially as the logic and needs of the script change!