2013-03-01 124 views
2

我想將我的GLSL着色器存儲在我的可執行文件中以保持整潔,將函數內部的字符串定義爲將其加載到着色器對象中的字符串。函數已經返回?我應該以其他方式來做這件事嗎? (我記得讀一些有關資源文件,但我從來沒有使用過的),具有在函數內部定義的字符串,將其加載到着色器對象從堆棧取出字符串時,該功能具有從C中刪除字符串C

回答

2

我想保存我的整潔可執行文件在我的GLSL着色器,

有很少利用這一點,但我能理解的動機。

會在函數內部定義字符串,將函數加載到着色器對象中當函數返回時獲取從堆棧中移除的字符串?

這取決於你如何聲明它。如果你這樣寫:

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

字符串內存分配在堆棧上,並初始化與初始化器字符串文字的內容。字符串文字本身是指向可執行文件常量數據段中特定位置的指針。數據段根據需要映射到進程地址中(如同可執行文件的其餘部分一樣)

如果你把它寫成

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

變量string初始化爲指向常量數據段本身,文字字符串的位置。沒有分配內存的一部分,從磁盤讀取的內容只當文字所在的頁面被實際訪問時

從技術角度來看,訪問字符串文字會爲數據訪問的mmap文件添加完全相同的內存和I/O開銷。事實上,可執行文件本身是mmap-ed,所以這是對mmap-ed文件的訪問。


[1]可執行文件在等待的時間很長一段阻塞系統調用最終會被換出的系統內存。如果在系統調用返回他們被換回來。實際上,在現代操作系統中,所有系統內存都被視爲塊I/O高速緩存,並且進程內存分配被視爲塊設備的內容(這使得實現交換空間變得微不足道)。如果沒有支持塊設備,則作爲進程內存的「高速緩存」將變爲不可擦除。

+0

非常感謝您的回答。標記。 :) – Erkling 2013-03-01 16:55:44

1

會回?

是的。一旦函數將控件返回給調用者,堆棧總是「彈出」。

我應該這樣做一些其他的方式呢?

最好從文件中加載它。這樣,您只能暫時佔用資源(即將文件映射到虛擬內存,將其傳輸到設備,然後取消映射文件)。

如果這不是一個選項,那麼最好在靜態全局內存中定義數據,以便它最終被放入程序的"Data" segment。這樣它就不會佔用靜態內存和堆棧(因爲否則它必須從某處加載到堆棧的內存中,無論如何這可能是一個「數據」段)。例如:

void load_data() 
{ 
    static const unsigned char mydata[] = { 0x01, 0x02, ... }; 
    /* Do something with "mydata" */ 
} 
+0

僅當需要時,可執行文件二進制「數據」段的元素纔會交換到進程地址空間。即只讀數據段中的字符串文字與mmaped文件內容的行爲完全相同。事實上,可執行文件本身只是一個mmap到各個部分。以上內容適用於支持文件內存映射的所有現代操作系統。 – datenwolf 2013-03-01 16:42:07

+0

@datenwolf:他們以後會自動取消映射以釋放一些頁面嗎?如果是,何時? – 2013-03-01 16:43:44

+0

是的,他們這樣做,當操作系統認爲合適時。通常,當進程阻塞在系統調用時,並且沒有其他使用該頁面駐留的頁面運行的可執行實例。現代OS的這種特定行爲呈現新的Linux PID = 1進程「systemd」的整個開始點播功能,無意義。但它也適用於Windows,* BSD和MacOS。 – datenwolf 2013-03-01 16:52:57