我一直在研究一個框架來幫助功能模板的即時通訊。我有一堆函數,用整數值爲模板進行優化,需要在運行時進行實例化和選擇。甲用法例子如下:需要幫助清理模板即時框架
// Function to instantiate templates of.
template<int a, int b, int c> void MyFunction(float, double){};
// List of values to substitute into each template parameter.
typedef mpl::vector_c< int, 7, 0, 3, 4, 2> valuesToInstantiate;
int numberOfValuesPerParameter = size<valuesToInstantiate>::type::value;
// Function pointer type. Must define type for array to hold template instantiations.
typedef void (*MyFunctionPointer)(float, double);
// Array to hold template instantiations.
// Accessed at runtime to get proper instantiation.
MyFunctionPointer arrayOfTemplateInstantiations[numberOfValuesPerParameter*numberOfValuesPerParameter*numberOfValuesPerParameter];
// Passed to template instantiation framework.
// AddTemplate member function will be called once per template value combo (3 int values).
// templateIndex indicates where to store the instantation in the array.
// templateSequence contains the template value combo (3 int values).
template<int templateIndex, typename templateSequence>
struct MyFunctionTemplateCreator
{
static void AddTemplate(void)
{
// Store template instantiation in array.
arrayOfTemplateInstantiations[templateIndex] = MyFunction
<
mpl::at<templateSequence, mpl::int_<0> >::type::value,
mpl::at<templateSequence, mpl::int_<1> >::type::value,
mpl::at<templateSequence, mpl::int_<2> >::type::value
>;
}
};
// List of lists where each inner list contains values to instantiate
// for the corresponding template parameter. E.g. each value in the first
// inner list will be passed into the first template parameter of MyFunction
typedef mpl::vector< valuesToInstantiate, valuesToInstantiate, valuesToInstantiate > templatesToCreate;
// Call template instantation framework to instantiate templates.
CreateTemplates<MyFunctionTemplateCreator, templatesToCreate> unusedVariable;
// Call proper template instantation at runtime...using index 5 arbitrarily for example.
arrayOfTemplateInstantiations[5](1.5, 2.0);
所以在這例子中,我實例MyFunction的,這需要3的整數值,與{ {7, 0, 3, 4, 2}, {7, 0, 3, 4, 2}, {7, 0, 3, 4, 2} }
每個組合。我省略了CreateTemplates的實現,因爲它很長,但它使用boost MPL for_each實現。上面的代碼對於我想要做的每個函數都是必需的,雖然它比寫出512個顯式實例要短,但它仍然有點長。令人驚訝的是,我想要爲每個函數編寫的最長代碼是函數指針的typedef,因爲許多函數需要10+個參數。有沒有辦法將這些模板實例存儲在一個更通用類型的數組中?
爲了論證的緣故,您可以假定模板參數總是像整個示例一樣的整數值,這樣模板實例化的簽名對於給定的函數模板都是相同的。實例化的函數全部在全局名稱空間中,而不是成員函數(它們實際上是CUDA內核)。任何其他技巧來清理這一點,將不勝感激。
注意:使用C++ 03
編輯:我想解決TarmoPikaro的什麼我試圖完成的問題。
我正在與一個應用程序,其中最多4個任務/線程將共享一個GPU來完成他們的工作(相同的工作,不同的數據)。由於我們的一些CUDA內核使用紋理,因此我們需要在運行時動態提供可用的紋理。我們堅持支持傳統的CUDA計算功能,這意味着紋理對象不能作爲函數參數傳遞,並且必須是靜態全局變量。爲了讓出紋理CPU的任務/線程,然後,我們給出了質地指數和我們的CUDA內核有這樣的語句:
// (variables t_int_2d_N are texture objects)
if (maskTextureIndex == 0)
maskValue = tex2D(t_int_2d_0, (float(p) + 0.5f)*maskScale.x + maskShift.x, (float(q) + 0.5f)*maskScale.y + maskShift.y)
else if (maskTextureIndex == 1)
maskValue = tex2D(t_int_2d_1, (float(p) + 0.5f)*maskScale.x + maskShift.x, (float(q) + 0.5f)*maskScale.y + maskShift.y)
else if (maskTextureIndex == 2)
maskValue = tex2D(t_int_2d_2, (float(p) + 0.5f)*maskScale.x + maskShift.x, (float(q) + 0.5f)*maskScale.y + maskShift.y)
else if (maskTextureIndex == 3)
maskValue = tex2D(t_int_2d_3, (float(p) + 0.5f)*maskScale.x + maskShift.x, (float(q) + 0.5f)*maskScale.y + maskShift.y)
else if (maskTextureIndex == 4)
maskValue = tex2D(t_int_2d_4, (float(p) + 0.5f)*maskScale.x + maskShift.x, (float(q) + 0.5f)*maskScale.y + maskShift.y)
else if (maskTextureIndex == 5)
maskValue = tex2D(t_int_2d_5, (float(p) + 0.5f)*maskScale.x + maskShift.x, (float(q) + 0.5f)*maskScale.y + maskShift.y)
else if (maskTextureIndex == 6)
maskValue = tex2D(t_int_2d_6, (float(p) + 0.5f)*maskScale.x + maskShift.x, (float(q) + 0.5f)*maskScale.y + maskShift.y)
else if (maskTextureIndex == 7)
maskValue = tex2D(t_int_2d_7, (float(p) + 0.5f)*maskScale.x + maskShift.x, (float(q) + 0.5f)*maskScale.y + maskShift.y)
有在內核中的一個循環語句是不可接受的性能損失。爲了避免性能損失,我們通過整數值(表示紋理索引)對內核進行模板化,以便將上述條件語句編譯出來。包含上述代碼的內核將被maskTextureIndex等於0-7的實例化,所以我們有8個不同的內核可以在運行時選擇。我們的一些內核最多使用3個紋理,並且我們允許每個紋理類型(例如float 1D,float 2D,float2 2D,int 3D等)具有索引0-7,這意味着我們必須實例化8 * 8 * 8 = 512個不同的內核來編譯出3個不同的條件語句,如上所述。我使用原始問題中的代碼,每個使用紋理的內核幫助實例化所有組合。
不幸的是,編程語言本身可以以任何方式進行定製,其中編程語言的原作者並沒有想過。這種濫用或濫用語言對於認爲他們已經到達蓋亞並可以隨意使用該語言的任何極端程序員是可能的。不幸的是,這樣的代碼變得越來越複雜,難以進一步維護和開發,而且很有可能在下一次迭代中另一位開發人員很可能會重寫您的解決方案。也許你可以更詳細地指定你想在最後達到什麼目的? – TarmoPikaro
@TarmoPikaro終於開始解決你的問題。不確定沒有升級到c + + 11有更好的解決方案。希望有人把這當作挑戰;)。 – user1777820