這是一個方法,我會嘗試:從數據結構的其餘部分分開的IsAlive的標誌。這看起來像是一段經常閱讀的數據,但很難寫出來。使用單個uint來跟蹤32個粒子的狀態。使用0表示活着,1表示死亡 - 實際上創建一個isDead列表。我假設你將擁有比死亡更多的活着粒子。
的值可以讀取(32一次),到時您需要本地內存。這允許你創建一個快速遍歷數據的內核,尋找一個非零值。這裏的性能提升帶來了密集的數據,從而減少了存儲和加載標誌的內存開銷。這使得檢查這些值中的一個成爲一個更便宜的操作,允許您更快速地遍歷它們。在更改32位值時您需要小心,以免損壞共享相同uint的其他數據(隔行掃描可能有助於此)。當你需要縮小1位的確切位置時,指令clz和popcount將會很有幫助。 opencl 1.2 refcard
可能的優化#1: 如果您願意,您可以嘗試隔行掃描值,以便第一個uint跟蹤索引0,32,64,96,...,992,第二個uint表示1,33 ,65,97,...,993等等。這可能允許通常在特定粒子上工作的工作項目讀取32個連續的isDead狀態。這可能會比努力付出更多努力,但這取決於您的應用程序。
可能的優化#2: 如果死粒子真的稀疏,可能值得它追蹤更高級別的isDead列表。使用相同的技術,很容易再次將isDead位/ uint列表減少32倍。第二級上的每個位代表相應的uint狀態。即:如果uint中的任何位被置位,則該列表的位N也將被置位。只有在數據中預計有很多零時纔有用,但是這一額外步驟可以節省大量搜索數據中罕見「開」位的週期。這包括原始isDead數據的總內存開銷將等於:memBits = ceil(particleCount/32)+ ceil(particleCount/32^2),或者對於每2^20個粒子約128kb + 4kb。
使用上面,就可以編寫內核,將返回死粒子的數量在給定的範圍內,並迅速找到下一個可用的死粒子之一。
來源
2013-01-22 03:03:21
mfa
因此,您不是將數據複製回主機,而是在每個時間步從主機調用不同的內核?另外,一旦粒子死了,除了被新的粒子取代之外,它能再次活躍嗎? – mfa
是的,我從不將數據複製回CPU。我重複一系列內核調用來每次更新粒子。是的,我一次又一次地重複使用了死亡的粒子,但隨後它成爲了物理世界中的新粒子,只是取代了舊的粒子的存儲區域,所以它與舊的粒子沒有任何關係。 –
你知道在給定的時間內有多少個死粒子嗎?你有足夠的內存來分配一個數組來跟蹤活動狀態嗎?你總共瞄準了多少粒子?你是在同一時間更換所有的死顆粒,還是可以等到更晚的時間步? – mfa