You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C语言无if三维点八分域计数实现及2^24规模点数组填充问题

问题原因分析

栈溢出错误成因

你定义的pnt arr[(1 << 24)]是局部栈上数组,2^24等于16777216个点,每个点占3个float共12字节,总大小约192MB,而操作系统给程序栈分配的内存通常只有8MB~32MB,远不足以容纳这么大的数组,因此触发栈溢出。

Release模式不执行代码原因

栈上分配超大数据属于未定义行为,Release模式下编译器检测到该非法操作,会直接优化删除相关代码段,因此看起来for循环和count函数没有执行。

正确实现方案

n=2^24的要求是指定测试用的点数量为16777216,用于放大两个版本的性能差异,你只需要把大数组从栈上分配改为堆上动态分配即可,具体实现如下:

1. 无if版统计函数实现

根据提示,八分域索引的每一位对应一个维度的正负判断:x非负对应索引第2位(值4)、y非负对应第1位(值2)、z非负对应第0位(值1),利用C语言布尔表达式返回1/0的特性直接拼接索引,全程无需if语句:

#include <string.h>

void count_no_if(pnt const* pnts, const int n, unsigned cnt[8]) {
    memset(cnt, 0, sizeof(unsigned) * 8);
    for (int i = 0; i < n; ++i) {
        int idx = ((pnts[i][0] >= 0.0f) << 2) | ((pnts[i][1] >= 0.0f) << 1) | (pnts[i][2] >= 0.0f);
        cnt[idx]++;
    }
}

2. 大数组分配与填充代码

改用malloc在堆上分配数组空间,堆内存上限远大于栈,完全可以容纳192MB的点数组:

#include <stdlib.h>
#include <stdio.h>

int main() {
    const int n = 1 << 24;
    // 堆上分配点数组
    pnt* arr = (pnt*)malloc(sizeof(pnt) * n);
    if (arr == NULL) {
        printf("内存分配失败\n");
        return 1;
    }
    // 填充随机点,注意循环边界修正为i < n
    for (int i = 0; i < n; i++) {
        for (int j = 0; j < 3; j++) {
            arr[i][j] = (float)((rand() % 100) - 50);
        }
    }
    unsigned cnt[8];
    // 测试两个版本的性能
    count(arr, n, cnt);
    // count_no_if(arr, n, cnt);
    // 释放内存
    free(arr);
    return 0;
}
性能对比注意事项
  • 测试时建议开启编译器O2优化,避免调试信息干扰性能结果
  • 可以多次调用函数取平均耗时,降低随机误差
  • 带if版本因为分支不可预测,分支预测失败率高,性能会显著低于无分支版本

内容的提问来源于stack exchange,提问作者Leon

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.01 03:39:03