यदि आप वास्तव में 128-बिट पूर्णांक के साथ काम करना चाहते हैं तो आपको संरेखण के बारे में चिंता करने की आवश्यकता नहीं है। कोई वर्तमान आर्किटेक्चर नहीं, कोई मशीन जो पायथन चलती है, 128-बिट देशी पूर्णांक अंकगणितीय का समर्थन करती है। तो 128-बिट पूर्णांक 16-बाइट गठबंधन होने से कोई मशीन की आवश्यकता या लाभ नहीं होगा। बस उस उपयोगकर्ता परिभाषित संरचना का उपयोग करें और आप ठीक हो जाएंगे।
यदि आप वास्तव में पूछ रहे हैं तो 128-बिट वेक्टर प्रकारों के लिए समर्थन है तो आपको शायद उन्हें गठबंधन करने की आवश्यकता होगी। यही है, यदि आप उन्हें पायथन कोड में बना रहे हैं और उन्हें सी/सी ++ कोड के संदर्भ में पास कर रहे हैं तो आपको उन्हें गठबंधन करने की आवश्यकता है। आप उन्हें मूल्य से विश्वसनीय रूप से पास नहीं कर सकते हैं, स्टैच पर उन्हें ठीक से संरेखित करने के लिए सीटीपीएस प्राप्त करने का कोई तरीका नहीं है (यदि यह आर्किटेक्चर एबीआई द्वारा आवश्यक है)। सी/सी ++ से पायथन तक पारित वेक्टर संभवतः पहले ही ठीक से संरेखित किए जाएंगे। इसलिए, यदि आप इसे व्यवस्थित कर सकते हैं तो आपके सभी वैक्टर सी/सी ++ कोड में आवंटित किए गए हैं, आपको अपने उपयोगकर्ता परिभाषित संरचना के साथ भी ठीक होना चाहिए।
मान लीजिए कि आपको वास्तव में पाइथन कोड में गठबंधन वैक्टर बनाने की आवश्यकता है तो मैंने गठबंधन ctypes सरणी के लिए कोड शामिल किया है। मेरे पास अन्य प्रकार के प्रकारों को संरेखित करने के लिए कोड भी है जिन्हें मैंने कोड आकार में उचित रूप से शामिल नहीं किया है। अधिकांश उद्देश्यों के लिए Arrays पर्याप्त होना चाहिए। इन गठबंधन सरणी में कुछ सीमाएं हैं। यदि आप उन्हें सी/सी ++ कार्यों के मूल्य से पास करते हैं या यदि आप उन्हें संरचना या संघ में सदस्य के रूप में शामिल करते हैं तो उन्हें ठीक से संरेखित नहीं किया जाएगा। आप *
ऑपरेटर का उपयोग करके गठबंधन सरणी के गठबंधन सरणी बना सकते हैं।
नए संरेखित सरणी प्रकार बनाने के लिए aligned_array_type(ctypes-type, length, alignment)
का उपयोग करें। पहले से मौजूद सरणी प्रकार के गठबंधन संस्करण को बनाने के लिए aligned_type(ctypes-type, alignment)
का उपयोग करें।
import ctypes
ArrayType = type(ctypes.Array)
class _aligned_array_type(ArrayType):
def __mul__(self, length):
return aligned_array_type(self._type_ * self._length_,
length, self._alignment_)
def __init__(self, name, bases, d):
self._alignment_ = max(getattr(self, "_alignment_", 1),
ctypes.alignment(self))
def _aligned__new__(cls):
a = cls._baseclass_.__new__(cls)
align = cls._alignment_
if ctypes.addressof(a) % align == 0:
return a
cls._baseclass_.__init__(a) # dunno if necessary
ctypes.resize(a, ctypes.sizeof(a) + align - 1)
addr = ctypes.addressof(a)
aligned = (addr + align - 1) // align * align
return cls.from_buffer(a, aligned - addr)
class aligned_base(object):
@classmethod
def from_address(cls, addr):
if addr % cls._alignment_ != 0:
raise ValueError, ("address must be %d byte aligned"
% cls._alignment_)
return cls._baseclass_.from_address(cls, addr)
@classmethod
def from_param(cls, addr):
raise ValueError, ("%s objects may not be passed by value"
% cls.__name__)
class aligned_array(ctypes.Array, aligned_base):
_baseclass_ = ctypes.Array
_type_ = ctypes.c_byte
_length_ = 1
__new__ = _aligned__new__
_aligned_type_cache = {}
def aligned_array_type(typ, length, alignment = None):
"""Create a ctypes array type with an alignment greater than natural"""
natural = ctypes.alignment(typ)
if alignment == None:
alignment = typ._alignment_
else:
alignment = max(alignment, getattr(typ, "_alignment_", 1))
if natural % alignment == 0:
return typ * length
eltsize = ctypes.sizeof(typ)
eltalign = getattr(typ, "_alignment_", 1)
if eltsize % eltalign != 0:
raise TypeError("type %s can't have element alignment %d"
" in an array" % (typ.__name__, alignment))
key = (_aligned_array_type, (typ, length), alignment)
ret = _aligned_type_cache.get(key)
if ret == None:
name = "%s_array_%d_aligned_%d" % (typ.__name__, length,
alignment)
d = {"_type_": typ,
"_length_": length,
"_alignment_": alignment}
ret = _aligned_array_type(name, (aligned_array,), d)
_aligned_type_cache[key] = ret
return ret
def aligned_type(typ, alignment):
"""Create a ctypes type with an alignment greater than natural"""
if ctypes.alignment(typ) % alignment == 0:
return typ
if issubclass(typ, ctypes.Array):
return aligned_array_type(typ._type_, typ._length_,
alignment)
else:
raise TypeError("unsupported type %s" % typ)
एक पैक की गई संरचना (_pack_ = 1) कम से कम संरेखण समस्या को हल करेगी। – epx
वास्तव में, इन वैक्टरों को सर्वश्रेष्ठ प्रदर्शन के लिए 16 बाइट्स के साथ गठित स्मृति पर आयोजित करने की आवश्यकता नहीं है। – Fil
नोट: http://stackoverflow.com/a/18531871/2419207 – iljau