SDCC和malloc()-分配的内存比可用内存少得多

SDCC和malloc()-分配的内存比可用内存少得多,c,malloc,sdcc,retro-computing,C,Malloc,Sdcc,Retro Computing,当我使用SDCC 3.1.0运行此代码,并在Amstrad CPC 464上运行它时(在仿真下,WineC 0.9.26在Wine上运行): void\u test\u malloc() { 长idx=0; 而(1) { if(malloc(5)) { printf(“%ld\r\n”++idx); } 其他的 { printf(“完成”); 打破 } } } 。。。它始终以92 malloc()s的速度输出。我制作了460字节,这就引出了几个问题: malloc()在这个系统上做什么?我希

当我使用SDCC 3.1.0运行此代码,并在Amstrad CPC 464上运行它时(在仿真下,WineC 0.9.26在Wine上运行):

void\u test\u malloc()
{
长idx=0;
而(1)
{
if(malloc(5))
{
printf(“%ld\r\n”++idx);
}
其他的
{
printf(“完成”);
打破
}
}
}
。。。它始终以92 malloc()s的速度输出。我制作了460字节,这就引出了几个问题:

  • malloc()在这个系统上做什么?我希望即使在64kB的系统上也能有一个数量级的存储空间

  • 该行为在64kB系统和128kB系统上是一致的;我是否需要执行某种魔法来访问额外的内存,比如手动切换银行


  • 答案是,在Z80系统上,堆大小硬编码为1kB。Maarten Brock在sdcc用户邮件列表中指出:

    你好,邓肯

    如果标准1kB不可用,您必须自己创建堆 足够地将heap.s复制到项目目录中,并对其进行修改以创建 首选尺寸。然后组装它并与您的项目链接

    与_heap.c中定义的mcs51堆不同,这不是 在手册中记录了Z80。请随时索取文档 在跟踪系统中更新或合并_heap.c和heap.s

    马丁


    事实上,正如Duncan Bayne所说,SDCC为Z80实现的默认内存管理器中有一个非常狭窄的堆空间

    然而,在尝试修改SDCC堆之前,您应该考虑在AMSTRAD CPC上是否确实需要动态内存。通常,在运行拥有整个硬件的独立应用程序时,使用动态内存是没有意义的。您可以测试并知道自己拥有多少内存,并且可以在任何需要的地方直接写入内存。没有内存保护,也没有在后台运行的其他应用程序

    因此,您最好设计自己的内存映射(您希望数据位于何处以及使用多少空间),然后直接管理内存。此外,代码优化在这台机器中非常重要,手动管理内存与优化非常相关


    如果您的代码直接在Amstrad CPC中运行(即不使用Symbos等现代操作系统),则必须手动处理银行切换以访问内存。Z80 CPU有一个16位总线,在不切换存储组的情况下只能寻址64KB的内存。

    为什么5字节递增?当您分配较大的块(只是出于好奇)时会发生什么?另一个问题:允许占用多少堆栈空间?静态内存分配的缺点是,即使应用程序无法同时填充所有缓冲区,您也必须为所有缓冲区的最坏情况限制付费。当然,在这样的系统上,成本也很高,但我肯定不会马上放弃动态分配(尽管generic
    malloc
    肯定已经过时了)。事实上,如果你想一想,这并不完全是一个缺点。如果您希望您的应用程序管理X数据,则需要可用的内存,否则将无法做到这一点。如果您是动态的,那么您也需要为堆分配空间。(继续…)在我看来,设计自己的内存池、为自己的不同目的服务并直接管理它通常更有趣。必须始终考虑最坏情况限制,尤其是在资源有限的情况下。总之,我的一般建议是事先考虑方法,而不是违约。剩下的只是我个人的观点。我想说的是,你可能正在写一个CPC游戏,一级需要很多动画,但是有一个小的地图区域,而二级有相反的要求。在这种情况下,两种资源类型之间的动态分割(无论是由
    malloc
    提供还是更可能是由自定义分配策略提供)提高了总体内存利用率。当然,需要采取的谨慎程度与内存预算的紧张程度成正比,但灵活方法的潜在好处也是如此。那么,我完全同意你的看法。我认为我们谈论的是相同的,但对于“动态”这个词,我们只是有不同的看法。