为什么我的小 C 循环不能正确打印到帧缓冲区,但它的展开版本可以?
Why doesn't my small C loop print correctly to the frame buffer, but its unrolled version does?
我正在尝试编写一个简单的 C 程序,在位置 (x, y) = (50, 50) 处绘制一个 4x4 像素的白色实心正方形。
想法是直接写入 Linux 帧缓冲区,它从映射内存 fb->fp 开始。
现在,问题是以下代码运行良好:
uint16_t color = 0xffff;
memcpy(fb->fp + (50+0) * fb->line_length + (50+0) * fb->bytes_per_pixel, &color, fb->bytes_per_pixel);
memcpy(fb->fp + (50+0) * fb->line_length + (50+1) * fb->bytes_per_pixel, &color, fb->bytes_per_pixel);
memcpy(fb->fp + (50+0) * fb->line_length + (50+2) * fb->bytes_per_pixel, &color, fb->bytes_per_pixel);
memcpy(fb->fp + (50+0) * fb->line_length + (50+3) * fb->bytes_per_pixel, &color, fb->bytes_per_pixel);
memcpy(fb->fp + (50+1) * fb->line_length + (50+0) * fb->bytes_per_pixel, &color, fb->bytes_per_pixel);
memcpy(fb->fp + (50+1) * fb->line_length + (50+1) * fb->bytes_per_pixel, &color, fb->bytes_per_pixel);
memcpy(fb->fp + (50+1) * fb->line_length + (50+2) * fb->bytes_per_pixel, &color, fb->bytes_per_pixel);
memcpy(fb->fp + (50+1) * fb->line_length + (50+3) * fb->bytes_per_pixel, &color, fb->bytes_per_pixel);
memcpy(fb->fp + (50+2) * fb->line_length + (50+0) * fb->bytes_per_pixel, &color, fb->bytes_per_pixel);
memcpy(fb->fp + (50+2) * fb->line_length + (50+1) * fb->bytes_per_pixel, &color, fb->bytes_per_pixel);
memcpy(fb->fp + (50+2) * fb->line_length + (50+2) * fb->bytes_per_pixel, &color, fb->bytes_per_pixel);
memcpy(fb->fp + (50+2) * fb->line_length + (50+3) * fb->bytes_per_pixel, &color, fb->bytes_per_pixel);
memcpy(fb->fp + (50+3) * fb->line_length + (50+0) * fb->bytes_per_pixel, &color, fb->bytes_per_pixel);
memcpy(fb->fp + (50+3) * fb->line_length + (50+1) * fb->bytes_per_pixel, &color, fb->bytes_per_pixel);
memcpy(fb->fp + (50+3) * fb->line_length + (50+2) * fb->bytes_per_pixel, &color, fb->bytes_per_pixel);
memcpy(fb->fp + (50+3) * fb->line_length + (50+3) * fb->bytes_per_pixel, &color, fb->bytes_per_pixel);
然而,下面没有。
它生成 1x4 线而不是 4x4 正方形。
uint16_t color = 0xffff;
int i = 0;
int j = 0;
for (; j < 4; j++) {
for (; i < 4; i++) {
int y_offset = 50 + j;
int x_offset = 50 + i;
memcpy(fb->fp + y_offset * fb->line_length + x_offset * fb->bytes_per_pixel,
&color, fb->bytes_per_pixel);
}
}
据我所知,它们应该是等价的。
我从编译器得到的汇编版本看起来不太好理解。
这在 ARM 嵌入式 Linux 设备中运行。
此时没有 X 服务器或任何其他内容写入帧缓冲区。
fb->bytes_per_pixel 等于 2.
我找不到任何关于帧缓冲区是如何映射到内存的文档。我得到的偏移量来自我在 Google.
上找到的随机代码
也许这些偏移量有问题。
但至少这两个代码应该是等价的,不是吗?
我要疯了吗?
这是问题所在:
for (; j < 4; j++) {
for (; i < 4; i++) {
//some code
}
}
外for
循环预计执行4次,这一定是因为循环体中没有条件break;
语句。
然而,内部 for
循环需要更改。对于外部 for
循环的第一次迭代,内部 for
循环按预期执行了 4 次。
外层for
循环的第二次迭代,i
的值为4
,内层for
循环的条件i>4
为假,所以不会'执行。外部 for
循环的所有下一次迭代都会发生同样的情况。
您可以通过为外部 for
循环的每次迭代初始化 i
来克服这个问题。
选项 1:
for( ; j < 4; j++)
{
for (i = 0; i < 4; i++)
{
// Some code
}
}
选项 2:
for( ; j < 4; j++)
{
for (; i < 4; i++)
{
// Some code
}
i = 0;
}
选项 3:
for( ; j < 4; j++)
{
i = 0;
for ( ; i < 4; i++)
{
// Some code
}
}
选项 4:根据 David C. Rankin 的建议:
int j = 0;
// int i = 0;
for( ; j < 4; j++)
{
int i = 0;
for ( ; i < 4; i++)
{
// Some code
}
}
我正在尝试编写一个简单的 C 程序,在位置 (x, y) = (50, 50) 处绘制一个 4x4 像素的白色实心正方形。
想法是直接写入 Linux 帧缓冲区,它从映射内存 fb->fp 开始。
现在,问题是以下代码运行良好:
uint16_t color = 0xffff;
memcpy(fb->fp + (50+0) * fb->line_length + (50+0) * fb->bytes_per_pixel, &color, fb->bytes_per_pixel);
memcpy(fb->fp + (50+0) * fb->line_length + (50+1) * fb->bytes_per_pixel, &color, fb->bytes_per_pixel);
memcpy(fb->fp + (50+0) * fb->line_length + (50+2) * fb->bytes_per_pixel, &color, fb->bytes_per_pixel);
memcpy(fb->fp + (50+0) * fb->line_length + (50+3) * fb->bytes_per_pixel, &color, fb->bytes_per_pixel);
memcpy(fb->fp + (50+1) * fb->line_length + (50+0) * fb->bytes_per_pixel, &color, fb->bytes_per_pixel);
memcpy(fb->fp + (50+1) * fb->line_length + (50+1) * fb->bytes_per_pixel, &color, fb->bytes_per_pixel);
memcpy(fb->fp + (50+1) * fb->line_length + (50+2) * fb->bytes_per_pixel, &color, fb->bytes_per_pixel);
memcpy(fb->fp + (50+1) * fb->line_length + (50+3) * fb->bytes_per_pixel, &color, fb->bytes_per_pixel);
memcpy(fb->fp + (50+2) * fb->line_length + (50+0) * fb->bytes_per_pixel, &color, fb->bytes_per_pixel);
memcpy(fb->fp + (50+2) * fb->line_length + (50+1) * fb->bytes_per_pixel, &color, fb->bytes_per_pixel);
memcpy(fb->fp + (50+2) * fb->line_length + (50+2) * fb->bytes_per_pixel, &color, fb->bytes_per_pixel);
memcpy(fb->fp + (50+2) * fb->line_length + (50+3) * fb->bytes_per_pixel, &color, fb->bytes_per_pixel);
memcpy(fb->fp + (50+3) * fb->line_length + (50+0) * fb->bytes_per_pixel, &color, fb->bytes_per_pixel);
memcpy(fb->fp + (50+3) * fb->line_length + (50+1) * fb->bytes_per_pixel, &color, fb->bytes_per_pixel);
memcpy(fb->fp + (50+3) * fb->line_length + (50+2) * fb->bytes_per_pixel, &color, fb->bytes_per_pixel);
memcpy(fb->fp + (50+3) * fb->line_length + (50+3) * fb->bytes_per_pixel, &color, fb->bytes_per_pixel);
然而,下面没有。 它生成 1x4 线而不是 4x4 正方形。
uint16_t color = 0xffff;
int i = 0;
int j = 0;
for (; j < 4; j++) {
for (; i < 4; i++) {
int y_offset = 50 + j;
int x_offset = 50 + i;
memcpy(fb->fp + y_offset * fb->line_length + x_offset * fb->bytes_per_pixel,
&color, fb->bytes_per_pixel);
}
}
据我所知,它们应该是等价的。 我从编译器得到的汇编版本看起来不太好理解。
这在 ARM 嵌入式 Linux 设备中运行。 此时没有 X 服务器或任何其他内容写入帧缓冲区。
fb->bytes_per_pixel 等于 2.
我找不到任何关于帧缓冲区是如何映射到内存的文档。我得到的偏移量来自我在 Google.
上找到的随机代码也许这些偏移量有问题。 但至少这两个代码应该是等价的,不是吗? 我要疯了吗?
这是问题所在:
for (; j < 4; j++) {
for (; i < 4; i++) {
//some code
}
}
外for
循环预计执行4次,这一定是因为循环体中没有条件break;
语句。
然而,内部 for
循环需要更改。对于外部 for
循环的第一次迭代,内部 for
循环按预期执行了 4 次。
外层for
循环的第二次迭代,i
的值为4
,内层for
循环的条件i>4
为假,所以不会'执行。外部 for
循环的所有下一次迭代都会发生同样的情况。
您可以通过为外部 for
循环的每次迭代初始化 i
来克服这个问题。
选项 1:
for( ; j < 4; j++)
{
for (i = 0; i < 4; i++)
{
// Some code
}
}
选项 2:
for( ; j < 4; j++)
{
for (; i < 4; i++)
{
// Some code
}
i = 0;
}
选项 3:
for( ; j < 4; j++)
{
i = 0;
for ( ; i < 4; i++)
{
// Some code
}
}
选项 4:根据 David C. Rankin 的建议:
int j = 0;
// int i = 0;
for( ; j < 4; j++)
{
int i = 0;
for ( ; i < 4; i++)
{
// Some code
}
}