2012-10-15 17 views
6

में 3 पूर्णांक कुंजी लुकअप मैं लगभग दस लाख अंकों के बड़े डेटा सेट में 3 पूर्णांक (यानी [1 2 3]) देखना चाहता हूं। 1 लाख अंक * 55 हमें 55 सेकंड = -सीयूडीए

key = sprintf('%d ', [1 2 3]);  % 23 us 
% key = '1 2 3 ' 
result = lookup_map(key);   % 32 us 

यह काफी समय लगता है, हालांकि:

मैं वर्तमान में MATLAB के मानचित्र (hashmap) का उपयोग कर रहा है, और प्रत्येक बिंदु के लिए मैं निम्नलिखित कर रहा हूँ।

मैं इसे सीयूडीए का उपयोग करके जीपीयू में ले जाना चाहता हूं, लेकिन मुझे यह सुनिश्चित करने का सबसे अच्छा तरीका नहीं है।

मैं चार सरणी - key1, key2, key3, result स्थानांतरित कर सकता हूं, और उसके बाद कुंजी पर बाइनरी खोज कर सकता हूं, लेकिन इसमें 20 पुनरावृत्तियों (2^20 = 1048576) प्रति कुंजी लगेगी। तो मुझे प्रत्येक धागे से समवर्ती स्मृति पहुंच के कारण देरी भी होगी।

क्या सीयूडीए में समानांतर (ओ (1), आदर्श) एकाधिक कुंजी लुकअप के लिए अनुकूलित डेटा संरचना है?


प्रश्न: तीन पूर्णांकों की सीमा क्या हैं? और क्या डेटा देखा जाता है?

पूर्णांक कुंजी वर्तमान में 0 और ~ 75,000 के बीच हो सकती है, लेकिन भविष्य में बड़ी (200,000+) हो सकती है।

इस प्रश्न के प्रयोजनों के लिए, हम मान सकते हैं कि result डेटा सेट के 0 और आकार के बीच एक पूर्णांक है।


प्र: आप एक 64 बिट संख्या में सभी तीन नंबर पैक नहीं है (संख्या के अनुसार 21 बिट्स आप 0-2,097,152 की एक श्रृंखला देता है)। और इसका उपयोग एक स्पैस सरणी में इंडेक्स करने के लिए करें?

>> A = uint64(ones(10)); 
>> sparse_A = sparse(A) 
??? Undefined function or method 'sparse' for input arguments of type 'uint64'. 

>> A = int64(ones(10)); 
>> sparse_A = sparse(A) 
??? Undefined function or method 'sparse' for input arguments of type 'int64'. 

ऐसा लगता है कि मेरी matlab 64-बिट संख्या के विरल सरणियों का समर्थन नहीं करता।

function [key] = to_key(face) 
    key = uint64(bitsll(face(1), 42) + bitsll(face(2), 21) + rand(face(3),1)); 
end 

प्रश्न::

मामले में यह किसी और में मदद करता है, मैं तीन < 2^21 अहस्ताक्षरित पूर्णांकों से एक 64-बिट कुंजी बनाने के लिए एक त्वरित समारोह लिखा @Dennis से - क्यों तार्किक अनुक्रमण का उपयोग नहीं करते?

चलिए इसका परीक्षण करें!

% Generate a million random integers between 0 and 1000 
>> M = int32(floor(rand(10000000,4)*1000)); 
% Find a point to look for 
>> search = M(500000,1:3)    
search = 
     850   910   581 
>> tic; idx = M(:,1)==search(1) & M(:,2)==search(2)&M(:,3)==search(3); toc; 
Elapsed time is 0.089801 seconds. 
>> M(idx,:) 
ans = 
     850   910   581   726 

दुर्भाग्य से यह 89801us लेता है, जो कि मेरे मौजूदा समाधान (55us) से 1632x धीमा है! इसे दस लाख बार चलाने में 2.5 घंटे लगेंगे!

हम प्रत्येक खोज के बाद M छानने की कोशिश कर सकते:

>> tic; idx1=M(:,1)==search(1); N=M(idx1,:); idx2=N(:,2)==search(2); N2=N(idx2,:); idx3 = N2(:,3)==search(3); toc; 
Elapsed time is 0.038272 seconds. 

यह एक छोटे से तेजी से होता है, लेकिन अभी भी 696x मानचित्र का उपयोग कर की तुलना में धीमी।


मैं कुछ और इस बारे में सोच रहा है, और मैं की गति प्रोफ़ाइल करने का निर्णय लिया एक भी कुंजी देखने से मक्खी पर डेटा के कुछ फिर से पैदा - यह एक 3 की तुलना में तेजी से हो सकता मुख्य दृष्टिकोण, इस दृष्टिकोण के साथ संभावित समस्याओं को देखते हुए।

+1

एक sidenote के रूप में, मैं चाहता हूं कि एनवीआईडीआईए मंच अभी भी सुलभ थे - वहां बहुत उपयोगी जानकारी थी। –

+0

तीन पूर्णांक की सीमाएं क्या हैं? और क्या डेटा देखा जाता है? –

+0

@ स्कीलरसेलेह आपकी रुचि के लिए धन्यवाद - मैंने अपने प्रश्न के लिए कुछ और जानकारी जोड़ दी है। –

उत्तर

2

मुझे लगता है कि यह प्रश्न आपके previous question से संबंधित है tetrahedron चेहरे के बारे में। मैं अभी भी सुझाव है कि आप उस उद्देश्य के लिए sparse भंडारण और विरल मैट्रिक्स वेक्टर गुणा प्रयास करना चाहिए:

size(spA) 
ans = 

1244810  1244810 

tic; 
vv = spA*v; 
idx = find(vv); 
toc; 

Elapsed time is 0.106581 seconds. 

यह सिर्फ विश्लेषण समय है, कैसे अपने मामले में इसे लागू करने के बारे में मेरे पिछले जवाब देखें। आप सीयूडीए में जाने से पहले और जटिल चीजें करने से पहले, सरल विकल्प देखें।

+0

हाहा मुझे अनुयायी मिला है! स्पैर मैट्रिस का उपयोग करने से दूर जाने का कारण यह है कि मैं अपने कंप्यूटर के लिए अधिकतम पूर्णांक आकार (2.1475e + 00 9) पर जाता हूं। अगर मेरे पास 75,000 टेट्रा जाल है, और इसलिए 75,000 * 4 चेहरे, 'v = sparse (ntetras * nfaces, 1) 'त्रुटि फेंकता है" स्पैर मैट्रिक्स आकार कंप्यूटर द्वारा परिभाषित MAXSIZE से कम गैर-ऋणात्मक पूर्णांक होना चाहिए " –

+0

क्या मैं सोचने में सही हूं कि अगर 'ntetras * nfaces <= 2.1475e + 009', और 'nfaces = 4 * ntetras', तो' ntetras <= sqrt (2.1475e + 009/4) '~ 2317? –

+0

@AlexL आपकी समस्या का आकार से संबंधित नहीं है। Matlab 'sparse' में' long' सूचकांक हैं और 2^64 के आकार वाले सिस्टम को संभाल सकते हैं .. और वैसे भी, 75000 * 4 = 300000 ... यह एक छोटी सी समस्या है। शायद आपके पास अन्य मुद्दे हैं। – angainor

0

ध्यान इस सवाल पहले से ही प्राप्त हुआ है यह लगता है इस जवाब की तरह बहुत आसान है, लेकिन क्यों आप सिर्फ इस तरह यह मत करो देखते हुए:

M=[1:6; 2:7; 3:8; 4:9]'; %Some matrix that contains key 1 2 3, corresponding value is 4 
idx=M(:,1)==1&M(:,2)==2&M(:,3)==3; 
M(idx,4) 

यह काफी तेजी से मूल्यांकन करना चाहिए, भले ही M है 1 मिलियन x 4.

+0

आपके उत्तर के लिए चीयर्स - मैंने इसका परीक्षण किया है, और यह मेरे मौजूदा समाधान की तुलना में ~ 1600 गुना धीमा है। यदि आप रुचि रखते हैं, तो मैंने अपने परिणामों के साथ अपना प्रश्न अपडेट कर लिया है! –

+1

समस्या यह है कि 'एम (:, 1) == 1' पहले पहले कॉलम की एक नई सरणी बनाता है, और उसके बाद इस नए सरणी के प्रत्येक मान की तुलना करता है (परिणाम मिलने पर रोक नहीं)। इसका मतलब है कि आपकी विधि 3 मिलियन बार लूप करेगी, साथ ही तीन नए सरणी बनाना होगा! –

+0

क्षमा करें, ऐसा प्रतीत होता है कि मैंने आपके प्रश्न को गलत समझा। मुझे लगता है कि आप एक लाख से 1 बिंदु खोजना चाहते थे। अब मैं यह पूछना चाहूंगा कि क्या आप 1 मिलियन अंक खोजना चाहते हैं (जो कई बार हो सकता है?) या उदाहरण के लिए प्रत्येक बिंदु बिल्कुल एक बार? उस मामले में मैं किसी प्रकार की सॉर्टिंग पर विचार करूंगा। –

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