void BlendBench::unalignedBlendArgb32() { const int dimension = 1024; // We use dst aligned by design. We don't want to test all the combination of alignemnt for src and dst. // Moreover, it make sense for us to align dst in the implementation because it is accessed more often. uchar *dstMemory = static_cast<uchar*>(qMallocAligned((dimension * dimension * sizeof(quint32)), 16)); QImage destination(dstMemory, dimension, dimension, QImage::Format_ARGB32_Premultiplied); destination.fill(0x12345678); // avoid special cases of alpha uchar *srcMemory = static_cast<uchar*>(qMallocAligned((dimension * dimension * sizeof(quint32)) + 16, 16)); QFETCH(int, offset); uchar *imageSrcMemory = srcMemory + (offset * sizeof(quint32)); QImage src(imageSrcMemory, dimension, dimension, QImage::Format_ARGB32_Premultiplied); src.fill(0x87654321); QPainter painter(&destination); QBENCHMARK { painter.drawImage(QPoint(), src); } qFreeAligned(srcMemory); qFreeAligned(dstMemory); }
void tst_QGuiMetaType::constructInPlace() { QFETCH(int, typeId); int size = QMetaType::sizeOf(typeId); void *storage = qMallocAligned(size, 2 * sizeof(qlonglong)); QCOMPARE(QMetaType::construct(typeId, storage, /*copy=*/0), storage); QMetaType::destruct(typeId, storage); QBENCHMARK { for (int i = 0; i < 100000; ++i) { QMetaType::construct(typeId, storage, /*copy=*/0); QMetaType::destruct(typeId, storage); } } qFreeAligned(storage); }
void tst_QGuiMetaType::constructInPlaceCopy() { QFETCH(int, typeId); int size = QMetaType::sizeOf(typeId); void *storage = qMallocAligned(size, 2 * sizeof(qlonglong)); void *other = QMetaType::create(typeId); QCOMPARE(QMetaType::construct(typeId, storage, other), storage); QMetaType::destruct(typeId, storage); QBENCHMARK { for (int i = 0; i < 100000; ++i) { QMetaType::construct(typeId, storage, other); QMetaType::destruct(typeId, storage); } } QMetaType::destroy(typeId, other); qFreeAligned(storage); }
/*! Creates a new node inside the data structure. \a update is an array with pointers to the node after which the new node should be inserted. Because of the strange skip list data structure there could be several pointers to this node on different levels. \a offset is an amount of bytes that needs to reserved just before the QMapData::Node structure. \a alignment dictates the alignment for the data. \internal \since 4.6 */ QMapData::Node *QMapData::node_create(Node *update[], int offset, int alignment) { int level = 0; uint mask = (1 << Sparseness) - 1; while ((randomBits & mask) == mask && level < LastLevel) { ++level; mask <<= Sparseness; } if (level > topLevel) { Node *e = reinterpret_cast<Node *>(this); level = ++topLevel; e->forward[level] = e; update[level] = e; } ++randomBits; if (level == 3 && !insertInOrder) randomBits = qrand(); void *concreteNode = strictAlignment ? qMallocAligned(offset + sizeof(Node) + level * sizeof(Node *), alignment) : qMalloc(offset + sizeof(Node) + level * sizeof(Node *)); Q_CHECK_PTR(concreteNode); Node *abstractNode = reinterpret_cast<Node *>(reinterpret_cast<char *>(concreteNode) + offset); abstractNode->backward = update[0]; update[0]->forward[0]->backward = abstractNode; for (int i = level; i >= 0; i--) { abstractNode->forward[i] = update[i]->forward[i]; update[i]->forward[i] = abstractNode; update[i] = abstractNode; } ++size; return abstractNode; }
QContiguousCacheData *QContiguousCacheData::allocate(int size, int alignment) { return static_cast<QContiguousCacheData *>(qMallocAligned(size, alignment)); }
QVectorData *QVectorData::allocate(int size, int alignment) { return static_cast<QVectorData *>(alignment > alignmentThreshold() ? qMallocAligned(size, alignment) : qMalloc(size)); }
static inline void *qMapAllocate(int alloc, int alignment) { return alignment > qMapAlignmentThreshold() ? qMallocAligned(alloc, alignment) : ::malloc(alloc); }