2012-06-11 15 views
54

मैंने हाल ही में ओपनजीएल से ओपनसीएल तक अपना वॉल्यूमेराकास्टर पोर्ट किया है, जिसने रेकास्टर के प्रदर्शन को लगभग 9 0 प्रतिशत घटा दिया है। मैंने ओपनसीएल के इमेजम्प्लिंग कार्यों में प्रदर्शन में कमी को ट्रैक किया, जो संबंधित ओपनजीएल टेक्सचरम्प्लिंग कार्यों से बहुत धीमी है। इमेजम्प्लिंग कार्यों और बनावट नमूना कार्यों को हटाकर, दोनों रेकास्टर कार्यान्वयन के बारे में एक ही गति थी। विभिन्न हार्डवेयर पर कार्यों को आसानी से बेंच करने के लिए, और मेरे बाकी आरटीएस कोड में कुछ मूर्खतापूर्ण गलतियों को बाहर करने के लिए, मैंने एक छोटा बेंचमार्क लिखा है जो ओपनजीएल नमूना गति की तुलना ओपनजीएल नमूना गति से करता है और इसे विभिन्न मशीनों पर परीक्षण करता है लेकिन ओपनसीएल के पास अभी भी ओपनजीएल के प्रदर्शन का लगभग 10% था।Abysmal OpenCL ImageSampling प्रदर्शन बनाम OpenGL TextureSampling

बेंचमार्क के OpenCL HostCode (कम से कम यह का सबसे महत्वपूर्ण हिस्सा):

void OGLWidget::OCLImageSampleTest() 
{ 
    try 
    { 
    int size=8; 
    float Values[4*size*size*size]; 
    cl::Kernel kernel=cl::Kernel(program,"ImageSampleTest",NULL); 
    cl::ImageFormat FormatA(CL_RGBA,CL_FLOAT); 
    cl::Image3D CLImage(CLcontext, CL_MEM_READ_ONLY | CL_MEM_COPY_HOST_PTR ,FormatA,size,size,size,0,0,Values,NULL); 


    cl::ImageFormat FormatB(CL_RGBA,CL_UNSIGNED_INT8); 
    cl::Image2D TempImage(CLcontext, CL_MEM_WRITE_ONLY,FormatB,1024,1024,0,NULL,NULL); 


    kernel.setArg(0, CLImage); 
    kernel.setArg(1, TempImage); 



    cl::Sampler Samp; 
    Samp() = clCreateSampler(CLcontext(), CL_TRUE, CL_ADDRESS_REPEAT, CL_FILTER_LINEAR, NULL); 
    kernel.setArg(2, Samp); 

    QTime BenchmarkTimer=QTime(); 
    BenchmarkTimer.start(); 

    cl::KernelFunctor func = kernel.bind(queue, cl::NDRange(1024,1024), cl::NDRange(32,32)); 
    func().wait(); 

    int Duration = BenchmarkTimer.elapsed(); 
    printf("OCLImageSampleTest: %d ms \n", Duration); 
    } 
    catch (cl::Error& err) 
     { 
     std::cerr << "An OpenCL error occured, " << err.what() 
        << "\nError num of " << err.err() << "\n"; 
     return; 
     } 

} 

OpenCL कर्नेल:

void kernel ImageSampleTest(read_only image3d_t CoordTexture, write_only image2d_t FrameBuffer, sampler_t smp) 
{ 
int Screenx = get_global_id(0); 
int Screeny = get_global_id(1); 

int2 PositionOnScreen=(int2)(Screenx,Screeny) ; 

float4 Testvec=(float4)(1,1,1,1); 
for(int i=0; i< 2000; i++) 
{ 
Testvec+= read_imagef(CoordTexture,smp, (float4)(0+0.00000001*i,0,0,0)); // i makes sure that the compiler doesn't unroll the loop 
} 

uint4 ToInt=(uint4)((uint) (Testvec.x), (uint) (Testvec.y) ,(uint)(Testvec.z),1); 
write_imageui ( FrameBuffer, PositionOnScreen, ToInt); 

} 

ओपन एक फुलस्क्रीन ट्रैक्टर के लिए FragmentShader जो के रूप में टुकड़े की एक ही राशि है ओपनसीएल कर्नेल में काम आइटम हैं:

#version 150 
uniform sampler3D Tex; 
out vec4 FragColor; 

void main() 
{ 
FragColor=vec4(0,0,0,0); 
for(int i=0; i<2000; i++) 
{ 
FragColor+= texture(Tex,vec3(0+0.00000001*i,0,0),0); 
} 
} 

इसके अलावा मैंने पहले से ही कोशिश की है

-changing कार्यसमूह का आकार:: ई प्रदर्शन को बढ़ाने के लिए निम्न कोई प्रदर्शन वृद्धि

-Different हार्डवेयर: 280 GTX, 580 GTX, कुछ फर्मी Tessla कार्ड, उन सभी को ओपन बनाम OpenCL में एक ही निराशाजनक प्रदर्शन किया था

-Different बनावट प्रारूपों (तैरता के बजाय बाइट्स), विभिन्न पहुँच पैटर्न और अलग बनावट आकार: कोई वृद्धि

डेटा के लिए एक छवि के बजाय एक बफर उपयोग करना और नमूने के लिए एक स्वयं लिखा तीन-रैखिक प्रक्षेप समारोह सीएल कर्नेल में: ओपनसीएल प्रदर्शन में वृद्धि हुई लगभग 100%

- 3 डी छवि // बनावट की बजाय 2 डी छवि // बनावट का उपयोग करना: यह ओपनसीएल प्रदर्शन में 100% की वृद्धि हुई है, हालांकि ओपनजीएल प्रदर्शन बिल्कुल नहीं बदला गया है।

उपयोग करना "निकटतम" "रैखिक" प्रक्षेप के बजाय: नहीं प्रदर्शन परिवर्तन

यह छोड़ दिया मुझे सोच: मैं एक बहुत ही बेवकूफ गलती जो OpenCL प्रदर्शन कम हो जाती है किया? ओपनसीएल नमूना प्रदर्शन इतना कम क्यों है, हालांकि इसे उसी बनावट हार्डवेयर का उपयोग OpenGL के रूप में करना चाहिए? मेरा जटिल ट्रिलिनर इंटरपोलेशन फ़ंक्शन कार्यान्वयन अपने हार्डवेयर कार्यान्वयन से तेज क्यों है? मैं ओपनसीएल में नमूना प्रदर्शन कैसे बढ़ा सकता हूं ताकि मैं ओपनजीएल की तरह ही गति कर सकूं?

+0

क्या आपके पास नवीनतम ड्राइवर हैं? मुझे यकीन है कि ओपनजीएल बिट्स हाल ही में नहीं बदला है, लेकिन ओपनसीएल सामान होना चाहिए! – Ani

+0

हां, वे संस्करण 301.32 हैं; वही है जो एनवीडिया वर्तमान में अपने डाउनलोड पेज पर प्रदान करता है। – user1449137

+2

क्या आपने सीएल/जीएल इंटरऑप का उपयोग करने की कोशिश की है? (Http://www.khronos.org/registry/cl/sdk/1.0/docs/man/xhtml/clCreateFromGLTexture3D।एचटीएमएल) मैंने इसे अतीत में उपयोग किया है क्योंकि मैं ओपनजीएल का उपयोग करके गणना के साथ ओपनजीएल का उपयोग करके प्रतिपादन का एक उचित हिस्सा कर रहा था। यह शायद आपका अंतिम समाधान नहीं है - लेकिन यह वास्तविक समस्या पर प्रकाश डालने में मदद कर सकता है। – Ani

उत्तर

2

मुझे संदेह है कि कुछ वीडियो कार्ड पर नवीनतम एनवीडिया ड्राइवरों में ओपनसीएल के साथ कुछ समस्या है। Here और here उन लोगों के बारे में कुछ रिपोर्ट हैं। किसी अन्य परिवार से जीपीयू पर परीक्षण दोहराने का प्रयास करें।

संबंधित मुद्दे