2

为了简洁起见,我想将我的 GLSL 着色器存储在我的可执行文件中,如果函数内部定义的字符串会将它们加载到着色器对象中,那么当函数返回时,字符串是否会从堆栈中删除?我应该以其他方式代替吗?(我记得读过一些关于资源文件的东西,但我以前从未使用过那些)

4

2 回答 2

2

为了整洁,我想将我的 GLSL 着色器存储在我的可执行文件中,

这没什么用,但我能理解动机。

当函数返回时,将在函数内部定义将它们加载到着色器对象中的字符串会从堆栈中删除字符串吗?

这取决于你如何声明它。如果你写这样的东西:

void foo(…)
{
    char const string[] = "....";
}

字符串内存在堆栈上分配,并使用初始化字符串文字的内容进行初始化。字符串文字本身是指向可执行文件常量数据段中特定位置的指针。数据段根据需要映射到进程地址(与可执行文件的其余部分一样^1.

当函数返回时,内存被“释放”;从技术上讲,它只是回滚的堆栈指针。

如果你把它写成

void bar(...)
{
    char const * string = "....";
}

该变量string使用指向常量数据段本身部分的指针进行初始化,字符串文字所在的部分。没有分配内存,并且只有在实际访问文字所在的页面时才从磁盘读取内容。

从技术角度来看,访问字符串文字增加的内存和 I/O 开销与为数据访问映射文件所增加的内存和 I/O 开销完全相同。事实上,可执行文件本身是 mmap-ed,所以这已经是对 mmap-ed 文件的访问。


[1] 在阻塞系统调用处等待很长时间的可执行文件最终将被换出系统内存,如果当系统调用返回时,它们会被换回。事实上,在现代操作系统中,所有系统内存都被视为块 I/O 缓存,进程内存分配被视为块设备的内容(这使得实现交换空间变得微不足道);如果没有后备块设备,作为进程内存的“缓存”将变得不可交换。

于 2013-03-01T16:50:38.810 回答
1

当函数返回时,在函数内部定义将它们加载到着色器对象中的字符串是否会从堆栈中删除字符串?

是的。一旦函数将控制权返回给调用者,堆栈总是“弹出”。

我应该以其他方式代替吗?

最好从文件中加载它。这样,您只是暂时占用资源(即将文件映射到虚拟内存,将其传输到设备,然后取消映射文件)。

如果这不是一个选项,那么最好在静态全局内存中定义数据,以便最终将其放入程序的“数据”段中。这样它就不会同时占用静态内存和堆栈(因为否则它必须从某个地方加载到堆栈的内存中,无论如何这可能是一个“数据”段)。例如:

void load_data()
{
    static const unsigned char mydata[] = { 0x01, 0x02, ... };
    /* Do something with "mydata" */
}
于 2013-03-01T16:23:31.230 回答