ProcessingUnit::ProcessingUnit(const DeviceContext *context,
                               std::size_t bitsThread)
    : context(context), cmdQueue(context->getCommandQueue())
{
    auto programContext = context->getProgramContext();
    auto dlContext = programContext->getDeviceListContext();
    auto &clContext = dlContext->getClContext();
    auto &device = context->getDevice();

    auto bitsGlobal = programContext->getBitsGlobal();

    kernel = cl::Kernel(programContext->getProgram(), "des_kernel");

    items = std::size_t(1) << (bitsGlobal - bitsThread);
    resultBits = programContext->getVectorLevel() + bitsGlobal;

    groupSize = std::min(items, kernel.getWorkGroupInfo<CL_KERNEL_WORK_GROUP_SIZE>(device));
    groupCount = BLOCK_COUNT(groupSize, items);

    cdBaseBufferSize = (56 - bitsGlobal) * programContext->getVectorBytes();
    resultBufferSize = (MAX_FOUND_KEYS + 1) * sizeof(cl_uint);

    cdBaseBuffer = cl::Buffer(clContext, CL_MEM_READ_ONLY, cdBaseBufferSize);
    resultBuffer = cl::Buffer(clContext, CL_MEM_WRITE_ONLY, resultBufferSize);

    mappedCdBaseBuffer = cmdQueue.enqueueMapBuffer(
                cdBaseBuffer, true, CL_MAP_WRITE, 0, cdBaseBufferSize);
    mappedResultBuffer = nullptr;

    kernel.setArg<cl::Buffer>(0, programContext->getRefInputBuffer());
    kernel.setArg<cl::Buffer>(1, programContext->getRefOutputBuffer());
    kernel.setArg<cl::Buffer>(2, cdBaseBuffer);
    kernel.setArg<cl::Buffer>(3, resultBuffer);
    kernel.setArg<cl_uint>   (4, static_cast<cl_uint>(bitsThread));
}
Example #2
0
void mem_pool::pool_free( void* ptr, size_t bytes )
{
    if( ptr )
        pool_dealloc( ptr, bytes );

    if( bytes <= MEMORY_POOL_MAX )
    {
        int i;
        size_t index = LIST_INDEX( bytes );
        size_t blk_count = BLOCK_COUNT( index );
        mempage_t *erase = NULL, *prev = NULL, *curr = pool[index].first;

        if( pool_lock )
            pool_lock( index );

        while( curr )
        {
            if( curr->count != blk_count ) /* 判断是否是空闲页 */
            {
                prev = curr;
                curr = curr->next;
            }
            else
            {
                /* 从页面缓存中退出 */
                for( i = 0; i < MEMORY_POOL_BUFFER; ++i )
                {
                    if( pool[index].buffer[i] == curr )
                    {
                        pool[index].buffer[i] = NULL;
                        break;
                    }
                }

                if( prev )
                    prev->next = curr->next; /* 空闲页不在链首 */
                else
                    pool[index].first = curr->next; /* 空闲页在链首 */

                /* 将空闲页释放 */
                erase = curr;
                curr = curr->next;
                MEMFREE( erase );
                --( pool[index].useable );
            } /* end if */
        } /* end while */

        if( pool_unlock )
            pool_unlock( index );
    }
}
Example #3
0
		BlockPath BlockPath::Index(size_t blockIndex) {
			std::array<uint16_t, NODE_MAX_BLOCK_PATH> components;
			components.fill(0);
			
			if (blockIndex < BLOCK_COUNT(0)) {
				// Direct reference.
				components.at(0) = blockIndex;
				return BlockPath(1, components);
			}
			
			if (blockIndex < BLOCK_COUNT(1)) {
				// Single indirect.
				components.at(0) = NODE_SINGLE_INDIRECT_INDEX;
				components.at(1) = indirectOffset<0>(blockIndex);
				return BlockPath(2, components);
			}
			
			if (blockIndex < BLOCK_COUNT(2)) {
				// Double indirect.
				components.at(0) = NODE_DOUBLE_INDIRECT_INDEX;
				components.at(1) = indirectOffset<1>(blockIndex);
				components.at(2) = indirectOffset<0>(blockIndex);
				return BlockPath(3, components);
			}
			
			if (blockIndex < BLOCK_COUNT(3)) {
				// Triple indirect.
				components.at(0) = NODE_TRIPLE_INDIRECT_INDEX;
				components.at(1) = indirectOffset<2>(blockIndex);
				components.at(2) = indirectOffset<1>(blockIndex);
				components.at(3) = indirectOffset<0>(blockIndex);
				return BlockPath(4, components);
			}
			
			throw std::runtime_error("Block index exceeds triple indirect.");
		}
Example #4
0
	namespace FolderSync {
		
		// ------------- Configurable values.
		
		// Size of a block.
		constexpr size_t BLOCK_SIZE = 65536;
		
		// Size of a block ID.
		constexpr size_t BLOCK_ID_SIZE = 16;
		
		// Offset in a node block where size is stored.
		constexpr size_t NODE_SIZE_OFFSET = 0;
		
		// Offset in a node block where type is stored.
		constexpr size_t NODE_TYPE_OFFSET = 8;
		
		// Offset in the block where IDs are stored.
		constexpr size_t NODE_BLOCK_ID_OFFSET = 16;
		
		// Maximum blocks held by a block cache.
		constexpr size_t CACHE_MAX_BLOCKS = 8;
		
		// Number of indirects in a node's root block.
		constexpr size_t INDIRECT_COUNT = 3;
		
		// ------------- Calculated values.
		
		// Maximum node block path size.
		constexpr size_t NODE_MAX_BLOCK_PATH = INDIRECT_COUNT + 1;
		
		// Maximum references in node's root block.
		constexpr size_t NODE_ROOT_MAX_REFS = ((BLOCK_SIZE - NODE_BLOCK_ID_OFFSET) / BLOCK_ID_SIZE);
		
		// Maximum direct references in node's root block.
		constexpr size_t NODE_ROOT_MAX_DIRECT_REFS = NODE_ROOT_MAX_REFS - INDIRECT_COUNT;
		
		// Maximum references in node's indirect blocks.
		constexpr size_t NODE_MAX_INDIRECT_REFS = (BLOCK_SIZE / BLOCK_ID_SIZE);
		
		// Index of the single indirect in node's root block.
		constexpr size_t NODE_SINGLE_INDIRECT_INDEX = NODE_ROOT_MAX_DIRECT_REFS;
		
		// Index of the double indirect in node's root block.
		constexpr size_t NODE_DOUBLE_INDIRECT_INDEX = NODE_ROOT_MAX_DIRECT_REFS + 1;
		
		// Index of the triple indirect in node's root block.
		constexpr size_t NODE_TRIPLE_INDIRECT_INDEX = NODE_ROOT_MAX_DIRECT_REFS + 2;
		
		// Integer power.
		constexpr size_t INT_POW(size_t value, size_t power) {
			return power > 0 ? value * INT_POW(value, power - 1) : 1;
		}
		
		// Integer power sum (i.e. INT_POW_SUM(n, 2, c) = n^2 + n^1 + c).
		constexpr size_t INT_POW_SUM(size_t value, size_t power, size_t constant) {
			return power > 0 ? INT_POW(value, power) + INT_POW_SUM(value, power - 1, constant) :
				constant;
		}
		
		// Calculate blocks that can be referenced by an indirect level.
		constexpr size_t BLOCK_COUNT(size_t indirectLevel) {
			return INT_POW_SUM(NODE_MAX_INDIRECT_REFS, indirectLevel, NODE_ROOT_MAX_DIRECT_REFS);
		}
		
		// Maximum node size in blocks.
		constexpr size_t NODE_MAX_BLOCKS = BLOCK_COUNT(INDIRECT_COUNT);
		
		// Maximum node size in bytes.
		constexpr size_t NODE_MAX_BYTES = NODE_MAX_BLOCKS * BLOCK_SIZE;
		
	}
Example #5
0
void* mem_pool::pool_alloc( size_t bytes )
{
    void* ptr = NULL;

    if( bytes > MEMORY_POOL_MAX )
    {
        ptr = MEMALLOC( bytes );
    }
    else
    {
        size_t index = LIST_INDEX( bytes );

        if( pool_lock )
            pool_lock( index );

        if( pool[index].first && pool[index].useable > 0 )
        {
            int i;
            mempage_t *prev = NULL, *curr = NULL;

            /* 先查找页面缓存 */
            for( i = 0; i < MEMORY_POOL_BUFFER; ++i )
            {
                if( pool[index].buffer[i] )
                {
                    ptr = pool[index].buffer[i]->free;
                    pool[index].buffer[i]->free = pool[index].buffer[i]->free->next;
                    --( pool[index].buffer[i]->count );

                    /* 如果该页已无空闲块,则将该页自页面缓存中退出 */
                    if( pool[index].buffer[i]->count == 0 )
                    {
                        --( pool[index].useable );
                        pool[index].buffer[i] = NULL;
                    }
                    else
                    {
                        if( i > 0 )
                        {
                            /* 如果该页不在缓存首,则将该页调整至缓存首 */
                            pool[index].buffer[0] = pool[index].buffer[i];
                            pool[index].buffer[i] = NULL;
                        }
                    }

                    goto EXIT_POOL_ALLOC;
                }
            } /* end for */

            /* 页面缓存为空,则遍历链中的所有内存页寻找空闲的内存块 */
            curr = pool[index].first;
            while( curr )
            {
                if( curr->count == 0 ) /* 该页中没有空闲块 */
                {
                    /* 进入下一页 */
                    prev = curr;
                    curr = curr->next;
                }
                else /* 该页中有空闲块 */
                {
                    size_t page_count = 0; /* 统计遍历过的可用内存页 */
                    ptr = curr->free;
                    curr->free = curr->free->next;
                    --( curr->count );
                    if( curr->count == 0 )
                        --( pool[index].useable );

                    /* 继续遍历链表,寻找其他还有空闲块的页面,将之放入页面缓存 */
                    while( curr && page_count < pool[index].useable )
                    {
                        if( curr->count != 0 )
                        {
                            /* 页面缓存还有位置则放入页面缓存 */
                            if( page_count < MEMORY_POOL_BUFFER )
                                pool[index].buffer[page_count] = curr;

                            ++page_count;

                            /* 如果当前页未满并且不在链首,则将之移至链首 */
                            if( pool[index].first != curr )
                            {
                                prev->next = curr->next; /* 保存下一页 */
                                curr->next = pool[index].first;
                                pool[index].first = curr;
                                curr = prev->next; /* 进入下一页 */
                                continue;
                            }
                        }

                        /* 进入下一页 */
                        prev = curr;
                        curr = curr->next;
                    }

                    goto EXIT_POOL_ALLOC;
                } /* end else */
            } /* end while */
        } /* end if pool[index].useable > 0 */
        else
        {
            /* 该链下未分配内存页或无空闲块,此时需增加新的内存页 */
            mempage_t* pg = NULL;
            size_t blk_size = BLOCK_SIZE( index );

            /* 如果 page_size = 0,则计算该内存链下每个内存页需占用的字节数 */
            if( 0 == pool[index].page_size )
            {
                if( DEFAULT_PAGE_SIZE % blk_size == 0 )
                    pool[index].page_size = DEFAULT_PAGE_SIZE;
                else
                    pool[index].page_size = (DEFAULT_PAGE_SIZE / blk_size)
                                            * blk_size;
            }

            pg = (mempage_t*)MEMALLOC( sizeof(mempage_t)
                                       + pool[index].page_size );

            if( pg )
            {
                memblk_t* curr = NULL;
                size_t i, blk_count = BLOCK_COUNT( index );

                pg->next = pool[index].first;
                pool[index].first = pg;

                 /* 将内存页中的所有内存块串联成一个链表 */
                curr = (memblk_t*)((unsigned char*)pg + sizeof(mempage_t));
                pg->free = curr;
                for( i = 1; i < blk_count; ++i )
                {
                    curr->next = (memblk_t*)((unsigned char*)curr + blk_size);
                    curr = curr->next;
                }
                curr->next = NULL;

                ptr = pg->free;
                pg->free = pg->free->next;
                pg->count = blk_count - 1;
                ++( pool[index].useable );
                pool[index].buffer[0] = pg;
            }
        }

EXIT_POOL_ALLOC:
        if( pool_unlock )
            pool_unlock( index );
    } /* end else */

    if( ptr )
        ++pool_alloc_count;

    return ptr;
}