2015-12-11 2 views
0

Когда я компилирую код ниже, я получаю предупреждение:Разгрузка к интел 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(); 
} 

ответ

0

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

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

boost::alignment::aligned_allocator 

.. выравнивать элементы данных. Также не забудьте -DBOOST_ALIGN.

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

Смежные вопросы