That is somewhat surprising and I see similar - And not being a C programmer, and never being sure about pointers, I tried other means of updating the via pointer write but the same ballpark.I'm a bit shocked that one is about 18x faster than the other.
The difference in my Run in RAM test code was about a factor of 10 ...
Code:
FB_SIZE = 100 x 100 (10000)Direct 0 : 6000480 - 6000397 = 83Direct 1 : 6000634 - 6000550 = 84ViaPtr 0 : 6001412 - 6000706 = 706ViaPtr 1 : 6002141 - 6001490 = 651
Code:
FB_SIZE = 200 x 200 (40000)Direct 0 : 6600647 - 6600402 = 245Direct 1 : 6600983 - 6600718 = 265ViaPtr 0 : 6603663 - 6601070 = 2593ViaPtr 1 : 6606359 - 6603748 = 2611
Code:
FB_SIZE = 300 x 300 (90000)Direct 0 : 6000885 - 6000396 = 489Direct 1 : 6001478 - 6000956 = 522ViaPtr 0 : 6007361 - 6001547 = 5814ViaPtr 1 : 6013270 - 6007447 = 5823
Code:
set(PROJECT fb_timing_issue)cmake_minimum_required(VERSION 3.12)include($ENV{PICO_SDK_PATH}/external/pico_sdk_import.cmake)project(${PROJECT} C CXX ASM)pico_sdk_init()add_executable(${PROJECT} main.c)target_link_libraries(${PROJECT} pico_stdlib)target_compile_options(${PROJECT} PRIVATE -Wall -Werror)pico_add_extra_outputs(${PROJECT})pico_enable_stdio_usb(${PROJECT} 1)pico_enable_stdio_uart(${PROJECT} 0)pico_set_binary_type(${PROJECT} no_flash)
Code:
#include <stdio.h>#include "pico/stdlib.h"uint32_t startTime;uint32_t endTime;uint32_t elapsedTime;void StartTiming(char * msg) { printf("%s : ", msg); startTime = time_us_32();}void EndTiming(void) { endTime = time_us_32(); elapsedTime = endTime - startTime; printf("%ld - %ld = %ld\n", endTime, startTime, elapsedTime);}#define FB_WIDTH 100#define FB_HEIGHT 100#define FB_SIZE FB_WIDTH * FB_HEIGHTuint8_t frame_buff0[FB_SIZE];uint8_t frame_buff1[FB_SIZE];uint8_t * drawPtr;void DirectDraw(uint32_t draw_idx) { uint8_t rgb = 0xAC; for (uint32_t h = 0; h < FB_HEIGHT; h++) { for (uint32_t w = 0; w < FB_WIDTH; w++) { uint32_t pixel = (h * FB_WIDTH) + w; if (draw_idx == 0) { frame_buff0[pixel] = rgb; } else { frame_buff1[pixel] = rgb; } } }}void ViaPtrDraw(uint32_t draw_idx) { if (draw_idx == 0) { drawPtr = &frame_buff0[0]; } else { drawPtr = &frame_buff1[0]; } uint8_t rgb = 0xAC; for (uint32_t h = 0; h < FB_HEIGHT; h++) { for (uint32_t w = 0; w < FB_WIDTH; w++) { uint32_t pixel = (h * FB_WIDTH) + w; drawPtr[pixel] = rgb; // *(drawPtr+pixel) = rgb; } }}int main(void) { stdio_init_all(); while (!stdio_usb_connected()) { sleep_ms(100); } printf("FB_SIZE = %d x %d (%d)\n\n", FB_WIDTH, FB_HEIGHT, FB_SIZE); while (true) { StartTiming("Direct 0"); DirectDraw(0); EndTiming(); StartTiming("Direct 1"); DirectDraw(1); EndTiming(); StartTiming("ViaPtr 0"); ViaPtrDraw(0); EndTiming(); StartTiming("ViaPtr 1"); ViaPtrDraw(1); EndTiming(); printf("\n"); sleep_ms(10000); }}
Code:
for (uint32_t h = 0; h < FB_HEIGHT; h++) { for (uint32_t w = 0; w < FB_WIDTH; w++) { uint32_t pixel = (h * FB_WIDTH) + w;
Code:
for (uint32_t pixel = 0; pixel < FB_SIZE; pixel++) {
Code:
FB_SIZE = 300 x 300 (90000)# Nested forDirect 0 : 7200764 - 7200403 = 361# 489Direct 1 : 7201220 - 7200830 = 390# 522ViaPtr 0 : 7207103 - 7201299 = 5804# 5814ViaPtr 1 : 7212988 - 7207184 = 5804# 5823
Update : I modified the code and ran it on my Pi and it seemed pretty consistent there. Weird.
Code:
pi@Pi3B:~/mypico/fb_timing_issue $ gcc pi.cpi@Pi3B:~/mypico/fb_timing_issue $ ./a.outDirect 0 : 8645 - 4633 = 4012Direct 1 : 12667 - 8723 = 3944ViaPtr 0 : 16515 - 12706 = 3809ViaPtr 1 : 20316 - 16549 = 3767
Code:
pi@Pi3B:~/mypico/fb_timing_issue $ gcc -O3 pi.cpi@Pi3B:~/mypico/fb_timing_issue $ ./a.outDirect 0 : 5838 - 5621 = 217Direct 1 : 6140 - 5918 = 222ViaPtr 0 : 6945 - 6182 = 763ViaPtr 1 : 7598 - 6982 = 616
Statistics: Posted by hippy — Sun Jun 30, 2024 7:46 am