Выгрузка в intel MIC с использованием выровненных данных

Когда я компилирую код ниже, я получаю предупреждение:

src/parallel_hashing.cpp(50): warning #3218: *MIC* class/struct may fail when offloaded because this field is misaligned or contains data that is misaligned    __declspec(align(64)) list<HashEntry> mChains[TABLE_SIZE];
                                                                                                                                                                                                ^ 

хотя я думаю, что я позаботился обо всех необходимых выравниваниях. когда я выполняю это, я получаю ошибку сегментации.

Кто-нибудь знает, как я могу заставить это работать?

Код:

#pragma offload_attribute(push, target(mic))
#include <stdio.h>
#include <stdlib.h>
#include <omp.h>
#include <list>
#include <queue>
#define TABLE_SIZE 3019
#define NUM_OF_THREADS 60
#define HASHINH_PRIME 2654435761

using namespace std;

int Hash(int key)
{
    return (HASHINH_PRIME * key) % TABLE_SIZE;
}

class __declspec(align(64)) HashEntry
{
private:

    unsigned int mKey;
    int mDummy[5];

public:

    //Ctor
    HashEntry(unsigned int key)
    {
        mKey = key;
        for (int i = 0; i < 5; i++)
        {
            mDummy[i] = key + i;
        }
    }

    unsigned int GetKey()
    {
        return mKey; 
    }
};

class HashTable
{
private:
    unsigned int mMaxChainLength;
    __declspec(align(64)) list<HashEntry> mChains[TABLE_SIZE];

    void UpdateMaxChainLength()
    {
        int newMaxChainLength = 0;
        for (int i = 0; i < TABLE_SIZE; i++)
        {
            int currentLength = mChains[i].size();

            if (currentLength > newMaxChainLength)
            {
                newMaxChainLength = currentLength;
            }
        }

        mMaxChainLength = newMaxChainLength;
    }

    list<HashEntry>* GetChain(unsigned int key)
    {
        return &mChains[Hash(key)];
    }

public:

    HashTable()
    {
        mMaxChainLength = 0;
    }

    unsigned int GetMaxChainLength()
    {
        return mMaxChainLength;
    }

    void InsertKey(unsigned int key)
    {
        //create a new entry with the key
        HashEntry newEntry = HashEntry(key);

        //get the specific chain
        list<HashEntry>* chain = GetChain(key);

        //insert the new entry to the chain
        chain->insert(chain->end(), newEntry);

        //update mMaxChainLength if needed
        if (chain->size() > mMaxChainLength)
            mMaxChainLength = chain->size();
    }

    void DeleteKey(unsigned int key)
    {
        //get the specific chain
        list<HashEntry>* chain = GetChain(key);

        list<HashEntry>::iterator it = chain->begin();
        while (it != chain->end() && it->GetKey() != key)
        {
            it++;
        }

        if (it != chain->end())
        {
            chain->erase(it);

            //update mMaxChainLength if the chain (before delete of key) was in the size of mMaxChainLength
            if (chain->size() == mMaxChainLength - 1)
                UpdateMaxChainLength();
        }
    }

    bool SearchKey(unsigned int key)
    {
        //get the specific chain
        list<HashEntry>* chain = GetChain(key);

        list<HashEntry>::iterator it = chain->begin();
        while (it != chain->end() && it->GetKey() != key)
        {
            it++;
        }

        return (it != chain->end());
    }
};

HashTable mCoreTables[NUM_OF_THREADS]; 

#pragma offload_attribute(pop)

void CreateTables()
{
    //parallelize via OpenMP on MIC
    #pragma offload target(mic)
    #pragma omp parallel num_threads(NUM_OF_THREADS)
    {
        int core = omp_get_thread_num();
        for (int i=0; i<100; i++)
        {
            mCoreTables[core].InsertKey(i); //for example
        }
    }   
}

int main()
{
    omp_set_nested(1);
    omp_set_max_active_levels(2);
    omp_set_num_threads(NUM_OF_THREADS);

    CreateTables(); 
}

1 ответ

Вы подняли чуть более широкий вопрос: как выровнять данные в контейнере STL.

Ответ: подумайте об использовании

boost::alignment::aligned_allocator

.. чтобы выровнять данные членов. Также не забывайте -DBOOST_ALIGN.

Подробнее читайте здесь (листы 10 - 13 содержат более подробную информацию по вашему вопросу)

Другие вопросы по тегам