2013-06-18 5 views
5

से बड़ी मात्रा में बाइट डेटा स्थानांतरित करें मेरे पास एक जावा प्रोग्राम है जो कस्टम फ़ाइल प्रारूप में छवियों को प्रदर्शित करने के लिए डिज़ाइन किया गया है, JNI का उपयोग कर सी ++ लाइब्रेरी के माध्यम से पढ़ें। डेटा को सी ++ पक्ष पर एक चार सरणी में लोड किया जाता है, और जावा पक्ष पर एक बुफर्ड इमेज में स्थानांतरित किया जाता है। चूंकि छवि के अनुभागों को स्मृति से हटाया जा सकता है और इसे नियमित रूप से पुनः लोड करने की आवश्यकता है, इसलिए मैं इन परिचालनों को जितनी जल्दी हो सके चाहता हूं।प्रभावी रूप से सी ++ से जावा

जिस तरह से मैं वर्तमान में ऐसा कर रहा हूं, डेटा को फ़ाइल से सी ++ लाइब्रेरी की स्मृति में एक बफर में पढ़ा जाता है। BufferedImage को पॉप्युलेट करने के लिए, जावा कोड इस बफर से पढ़ने के लिए प्रत्येक पिक्सेल के लिए जेएनआई फ़ंक्शन कॉल करता है और यदि आवश्यक हो, तो बफर में डेटा का एक और हिस्सा लोड करें। यह काम करता है, लेकिन मुझे लगता है कि एक उच्च ओवरहेड के साथ।

जो मैं इसे सुधारने के लिए करने की योजना बना रहा हूं वह BufferedImage ऑब्जेक्ट को जेएनआई कॉल का उपयोग करके सी ++ कोड पर पास कर देता है, और उस तरफ से फ़ंक्शन कॉल करता है। मैं जेएनआई जितना कर सकता हूं उतना शोध कर रहा हूं, लेकिन मैं यह पता लगाने में सक्षम नहीं हूं कि जावा ऑब्जेक्ट्स को सी ++ लाइब्रेरी से संशोधित करने में कोई कीमत है या नहीं, जो कि जेवीएम द्वारा लोड किया गया था। क्या यह इसे लागू करने का एक अच्छा तरीका है, या क्या जेएनआई के साथ बड़ी मात्रा में बाइट डेटा स्थानांतरित करने का एक तेज़ तरीका है?

+4

प्रति कॉल एक पिक्सेल भयानक लगता है! बड़ी छवियों के लिए अरबों कॉल होंगे। ब्लॉक या रास्टर लाइनों (जैसे बड़ी छवि इकाइयां) को एक बार में लाने के बारे में क्या? क्या रास्टर लाइनों को क्रमशः पैक किया जा सकता है और अतिरिक्त रूपांतरणों से बच सकते हैं? – user2246674

+0

हां, रेखाएं और ब्लॉक दोनों को C++ पक्ष पर एक बफर में पढ़ा जा सकता है। मैंने C++ पक्ष पर अनुकूलित करने का थोड़ा सा किया है। समस्या यह है कि मुझे उस डेटा को जावा में स्थानांतरित करने का एक प्रभावी तरीका नहीं पता है, इसलिए मैं प्रत्येक पिक्सेल पर सी ++ बफर से डेटा पढ़ने के लिए एक अलग कॉल करता हूं। – resueman

+1

@resuerman कुछ [WritableRaster.setSamples] (http://docs.oracle.com/javase/1.5.0/docs/api/java/awt/image/WritableRaster.html#setSamples (int,% 20int,% 20int ,% 20int,% 20int,% 20double [])) का उपयोग किया जाना चाहिए? यदि ऐसा हो सकता है, तो यह जावा सरणी में डेटा (सबसे कुशलता से) लोड करने का तरीका ढूंढ सकता है। क्या कोई सरणी और/या रैप [सी ++] मेमोरी पिन करने और [प्राथमिक] प्रतिलिपि से बचने का कोई तरीका है? यहां तक ​​कि एक अतिरिक्त प्रतिलिपि ऑपरेशन (सी ++ -> जावा ऐरे-> रास्टर) के साथ, इसे अभी भी जेएनआई कॉल की संख्या को कम करना चाहिए। इसके अलावा (और मुझे लगता है कि यह "अतिरिक्त चालाक" लगता है), क्या ओपनजीएल (बनावट) का उपयोग यहां किया जा सकता है? – user2246674

उत्तर

1

जेएनआई सीमा में डेटा को स्थानांतरित करने का सबसे प्रभावी तरीका शायद ByteBuffers. के माध्यम से संभव है, आपको एक समय में जितना संभव हो उतना स्थानांतरित करना चाहिए, क्योंकि वह सीमा पार कर रहा है जो अक्षम है, हस्तांतरण नहीं। निश्चित रूप से एक पिक्सेल से अधिक, एक समय में अधिमानतः मेगाबाइट्स।

+0

बहुत बढ़िया। यह वैसे ही लगता है जो मैं खोज रहा था। धन्यवाद। – resueman

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