Beispiel #1
0
TTEntry* TranspositionTable::probe(const Key& key, bool& found) const {

  TTEntry* const tte = first_entry(key);

  for (int i = 0; i < ClusterSize; ++i)
    if (!tte[i].key64 || tte[i].key64 == key.p[1])
    {
      if ((tte[i].genBound8 & 0xFC) != generation8 && tte[i].key64)
        tte[i].genBound8 = uint8_t(generation8 | tte[i].bound()); // Refresh

      return found = tte[i].key64 != 0, &tte[i];
    }

  // Find an entry to be replaced according to the replacement strategy
  TTEntry* replace = tte;
  for (int i = 1; i < ClusterSize; ++i)
    // Due to our packed storage format for generation and its cyclic
    // nature we add 259 (256 is the modulus plus 3 to keep the lowest
    // two bound bits from affecting the result) to calculate the entry
    // age correctly even after generation8 overflows into the next cycle.
    if (replace->depth8 - ((259 + generation8 - replace->genBound8) & 0xFC) * 2 * OnePly
  >   tte[i].depth8 - ((259 + generation8 - tte[i].genBound8) & 0xFC) * 2 * OnePly)
      replace = &tte[i];

  return found = false, replace;
}
Beispiel #2
0
TTEntry* TranspositionTable::probe(const Key key, uint32_t h, bool& found) const {

  TTEntry* const tte = first_entry(key);
  const uint16_t key16 = key >> 48;  // Use the high 16 bits as key inside the cluster

  for (int i = 0; i < ClusterSize; ++i)
      if (!tte[i].key16 || (tte[i].key16 == key16 && tte[i].hand32 == h))
      {
          if ((tte[i].genBound8 & 0xFC) != generation8 && tte[i].key16)
              tte[i].genBound8 = uint8_t(generation8 | tte[i].bound()); // Refresh

          return found = (bool)tte[i].key16, &tte[i];
      }

  // Find an entry to be replaced according to the replacement strategy
  TTEntry* replace = tte;
  for (int i = 1; i < ClusterSize; ++i)
      // Due to our packed storage format for generation and its cyclic
      // nature we add 259 (256 is the modulus plus 3 to keep the lowest
      // two bound bits from affecting the result) to calculate the entry
      // age correctly even after generation8 overflows into the next cycle.
      if (  replace->depth8 - ((259 + generation8 - replace->genBound8) & 0xFC) * 2 * ONE_PLY
          >   tte[i].depth8 - ((259 + generation8 -   tte[i].genBound8) & 0xFC) * 2 * ONE_PLY)
          replace = &tte[i];

  return found = false, replace;
}
Beispiel #3
0
void TranspositionTable::store(const Key key, Value v, Bound b, Depth d, Move m, Value statV) {

    TTEntry *tte, *replace;
    uint32_t key32 = key >> 32; // Use the high 32 bits as key inside the cluster

    tte = replace = first_entry(key);

    for (unsigned i = 0; i < ClusterSize; ++i, ++tte)
    {
        if (!tte->key32 || tte->key32 == key32) // Empty or overwrite old
        {
            if (!m)
                m = tte->move(); // Preserve any existing ttMove

            replace = tte;
            break;
        }

        // Implement replace strategy
        if (  (    tte->generation8 == generation || tte->bound() == BOUND_EXACT)
                - (replace->generation8 == generation)
                - (tte->depth16 < replace->depth16) < 0)
            replace = tte;
    }

    replace->save(key32, v, b, d, m, generation, statV);
}
Beispiel #4
0
void TranspositionTable::store(const Key key, Value v, Bound b, Depth d, Move m, Value statV, Value evalM) {

  int c1, c2, c3;
  TTEntry *tte, *replace;
  uint32_t key32 = key >> 32; // Use the high 32 bits as key inside the cluster

  tte = replace = first_entry(key);

  for (unsigned i = 0; i < ClusterSize; i++, tte++)
  {
      if (!tte->key() || tte->key() == key32) // Empty or overwrite old
      {
          if (!m)
              m = tte->move(); // Preserve any existing ttMove

          replace = tte;
          break;
      }

      // Implement replace strategy
      c1 = (replace->generation() == generation ?  2 : 0);
      c2 = (tte->generation() == generation || tte->bound() == BOUND_EXACT ? -2 : 0);
      c3 = (tte->depth() < replace->depth() ?  1 : 0);

      if (c1 + c2 + c3 > 0)
          replace = tte;
  }

  replace->save(key32, v, b, d, m, generation, statV, evalM);
}
Beispiel #5
0
dl_dma_addr_t dl_dma_get_physical_segment(struct dl_dma_list* sl, void* address, unsigned long offset, unsigned long* length)
{
	struct dl_dma_entry* e = first_entry(sl);
	unsigned long page_offset;
	unsigned long page_num;
	unsigned long page_oip;
	
	if (sl->dma_is_single)
	{
		if (length)
			*length = sl->size - offset;
		return (dl_dma_addr_t)e->dma_addr + offset;
	}
	
	page_offset = (unsigned long)address % PAGE_SIZE;
	page_num = (page_offset + offset) / PAGE_SIZE;
	page_oip = (page_offset + offset) % PAGE_SIZE;

	if (page_num > sl->num_pages)
		return 0;
	
	e = get_entry(e, page_num);

	if (length)
		*length	= PAGE_SIZE - page_oip;

	return (dl_dma_addr_t)e->dma_addr + page_oip;
}
Beispiel #6
0
struct dl_dma_list* 
dl_dma_map_user_buffer(void* page_array, unsigned long num_pages, int direction, void* pdev)
{
	int i = 0;
	struct dl_dma_list* sl 				= NULL;
	struct dl_dma_entry *e				= NULL;
	struct page** pages = (struct page**)page_array;

	if (!page_array)
		return NULL;

	sl = alloc_dl_dma_entry(num_pages);
	if (!sl)
		return NULL;

	e = first_entry(sl);
	direction = bmd_to_linux_direction(direction);	

	for (i = 0; i < num_pages; i++)
	{
		e->dma_addr = pci_map_page(pdev, pages[i], 0, PAGE_SIZE, direction);
		e = next_entry(e);
	}

	sl->num_pages = num_pages;
	sl->pdev = pdev;	
	
	return sl;
}
void TranspositionTable::store(const Key posKey, Value v, ValueType t, Depth d, Move m, Value statV, Value kingD) {

  int c1, c2, c3;
  TTEntry *tte, *replace;
  uint32_t posKey32 = posKey >> 32; // Use the high 32 bits as key

  tte = replace = first_entry(posKey);
  for (int i = 0; i < ClusterSize; i++, tte++)
  {
      if (!tte->key() || tte->key() == posKey32) // empty or overwrite old
      {
          // Preserve any exsisting ttMove
          if (m == MOVE_NONE)
              m = tte->move();

          tte->save(posKey32, v, t, d, m, generation, statV, kingD);
          return;
      }

      if (i == 0)  // replace would be a no-op in this common case
          continue;

      c1 = (replace->generation() == generation ?  2 : 0);
      c2 = (tte->generation() == generation ? -2 : 0);
      c3 = (tte->depth() < replace->depth() ?  1 : 0);

      if (c1 + c2 + c3 > 0)
          replace = tte;
  }
  replace->save(posKey32, v, t, d, m, generation, statV, kingD);
  overwrites++;
}
Beispiel #8
0
const TTEntry* TranspositionTable::probe(const Key key) const {

  const TTEntry* tte = first_entry(key);
  uint32_t key32 = key >> 32;

  for (unsigned i = 0; i < ClusterSize; i++, tte++)
      if (tte->key() == key32)
          return tte;

  return NULL;
}
Beispiel #9
0
const TTEntry* TranspositionTable::probe(const Key key) const {

    TTEntry* tte = first_entry(key);
    uint32_t key32 = key >> 32;

    for (unsigned i = 0; i < ClusterSize; ++i, ++tte)
        if (tte->key32 == key32)
        {
            tte->generation8 = generation; // Refresh
            return tte;
        }

    return nullptr;
}
Beispiel #10
0
void dl_dma_unmap_kernel_buffer(struct dl_dma_list* sl, int direction)
{
	unsigned long i;
	struct dl_dma_entry *e = first_entry(sl);
	
	direction = bmd_to_linux_direction(direction);

	if (!sl->dma_is_single)
	{
		for (i = 0; i < sl->num_pages; i++)
		{
			pci_unmap_page(sl->pdev, e->dma_addr, PAGE_SIZE, direction);
			e = next_entry(e);
		}
	}
	else
		pci_unmap_single(sl->pdev, e->dma_addr, sl->size, direction);

	destroy_dl_dma_entry(sl);
}
Beispiel #11
0
struct dl_dma_list* 
dl_dma_map_kernel_buffer(void *address, unsigned long size, int direction, int is_vmalloc, void* pdev)
{
	struct page* page;
	int i = 0, offset = 0;
	struct dl_dma_list* sl 			= NULL;
	struct dl_dma_entry *e			= NULL;
	unsigned long num_pages 		= dl_dma_get_num_pages(address, size);
	unsigned long start_addr		= (unsigned long)address;

	start_addr = start_addr - (start_addr % PAGE_SIZE);

	sl = alloc_dl_dma_entry(is_vmalloc == 1 ? num_pages : 1);
	if (!sl)
		return NULL;

	e = first_entry(sl);
	direction = bmd_to_linux_direction(direction);
	
	if (is_vmalloc)
	{
		for (i = 0; i < num_pages; i++)
		{
			page = vmalloc_to_page((void*)(unsigned long)start_addr + offset);
			offset += PAGE_SIZE;
			e->dma_addr = pci_map_page(pdev, page, 0, PAGE_SIZE, direction);
			e = next_entry(e);
		}
		sl->num_pages = num_pages;
	}
	else
	{
		e->dma_addr = pci_map_single(pdev, address, size, direction);
		sl->dma_is_single = 1;
		sl->size = size;
	}
	sl->pdev = pdev;	
	return sl;
}
Beispiel #12
0
void TranspositionTable::store(const Key posKey, Value v, ValueType t, Depth d, Move16 m, Value statV, Value kingD) {
#else
void TranspositionTable::store(const Key posKey, Value v, ValueType t, Depth d, Move m, Value statV, Value kingD) {
#endif

  int c1, c2, c3;
  TTEntry *tte, *replace;
  uint32_t posKey32 = posKey >> 32; // Use the high 32 bits as key inside the cluster

  tte = replace = first_entry(posKey);

  for (int i = 0; i < ClusterSize; i++, tte++)
  {
      if (!tte->key() || tte->key() == posKey32) // Empty or overwrite old
      {
          // Preserve any existing ttMove
#ifdef GPSFISH
          if (m == MOVE16_NONE)
              m = tte->move16Val();
#else
          if (m == MOVE_NONE)
              m = tte->move();
#endif

          tte->save(posKey32, v, t, d, m, generation, statV, kingD);
          return;
      }

      // Implement replace strategy
      c1 = (replace->generation() == generation ?  2 : 0);
      c2 = (tte->generation() == generation || tte->type() == VALUE_TYPE_EXACT ? -2 : 0);
      c3 = (tte->depth() < replace->depth() ?  1 : 0);

      if (c1 + c2 + c3 > 0)
          replace = tte;
  }
  replace->save(posKey32, v, t, d, m, generation, statV, kingD);
}
    void ParsedName::List::count_dim (std::vector<int>& dim, size_t& current_entry, size_t current_dim) const
    {
      int n;
      bool stop = false;
      std::shared_ptr<const ParsedName> first_entry ( list[current_entry]);

      for (n = 0; current_entry < size(); n++) {
        for (size_t d = 0; d < current_dim; d++)
          if ( list[current_entry]->index (d) != first_entry->index (d)) 
            stop = true;
        if (stop) 
          break;

        if (current_dim < list[0]->ndim()-1)
          count_dim (dim, current_entry, current_dim+1);
        else current_entry++;
      }

      if (dim[current_dim] && dim[current_dim] != n)
        throw Exception ("number mismatch between number of images along different dimensions");

      dim[current_dim] = n;
    }
Beispiel #14
0
TTEntry* TranspositionTable::probe(const Key key, bool& found) const {

  TTEntry* const tte = first_entry(key);
  const uint16_t key16 = key >> 48;  // Use the high 16 bits as key inside the cluster

  for (int i = 0; i < ClusterSize; ++i)
      if (!tte[i].key16 || tte[i].key16 == key16)
      {
          if (tte[i].key16)
              tte[i].genBound8 = uint8_t(generation8 | tte[i].bound()); // Refresh

          return found = (bool)tte[i].key16, &tte[i];
      }

  // Find an entry to be replaced according to the replacement strategy
  TTEntry* replace = tte;
  for (int i = 1; i < ClusterSize; ++i)
      if (  ((  tte[i].genBound8 & 0xFC) == generation8 || tte[i].bound() == BOUND_EXACT)
          - ((replace->genBound8 & 0xFC) == generation8)
          - (tte[i].depth8 < replace->depth8) < 0)
          replace = &tte[i];

  return found = false, replace;
}
Beispiel #15
0
      if (c1 + c2 + c3 > 0)
          replace = tte;
  }
  replace->save(posKey32, v, t, d, m, generation, statV, kingD);
}


/// TranspositionTable::probe() looks up the current position in the
/// transposition table. Returns a pointer to the TTEntry or NULL if
/// position is not found.

TTEntry* TranspositionTable::probe(const Key posKey) const {

  uint32_t posKey32 = posKey >> 32;
  TTEntry* tte = first_entry(posKey);

  for (int i = 0; i < ClusterSize; i++, tte++)
      if (tte->key() == posKey32)
          return tte;

  return NULL;
}


/// TranspositionTable::new_search() is called at the beginning of every new
/// search. It increments the "generation" variable, which is used to
/// distinguish transposition table entries from previous searches from
/// entries from the current search.

void TranspositionTable::new_search() {
Beispiel #16
0
TTEntry* TranspositionTable::probe(const Key key, bool& found
#if defined(USE_GLOBAL_OPTIONS)
	, size_t thread_id
#endif
	
	) const
{
	ASSERT_LV3(clusterCount != 0);

#if defined(USE_GLOBAL_OPTIONS)
	if (!GlobalOptions.use_hash_probe)
	{
		// 置換表にhitさせないモードであるなら、見つからなかったことにして
		// つねに確保しているメモリの先頭要素を返せば良い。(ここに書き込まれたところで問題ない)
		return found = false, first_entry(0);
	}
#endif

	// 最初のTT_ENTRYのアドレス(このアドレスからTT_ENTRYがClusterSize分だけ連なっている)
	// keyの下位bitをいくつか使って、このアドレスを求めるので、自ずと下位bitはいくらかは一致していることになる。
	TTEntry* tte;
	u8 gen8;

#if !defined(USE_GLOBAL_OPTIONS)

	tte = first_entry(key);
	gen8 = generation();

#else

	if (GlobalOptions.use_per_thread_tt)
	{
		// スレッドごとに置換表の異なるエリアを渡す必要がある。
		// 置換表にはclusterCount個のクラスターがあるのでこれをスレッドの個数で均等に割って、
		// そのthread_id番目のblockを使わせてあげる、的な考え。
		//
		// ただしkeyのbit0は手番bitであり、これはそのままindexのbit0に反映されている必要がある。
		//
		// また、blockは2の倍数になるように下丸めしておく。
		// ・上丸めするとblock*max_thread > clusterCountになりかねない)
		// ・2の倍数にしておかないと、(key % block)にkeyのbit0を反映させたときにこの値がblockと同じ値になる。
		//   (各スレッドが使えるのは、( 0~(block-1) ) + (thread_id * block)のTTEntryなので、これはまずい。

		size_t block = (clusterCount / max_thread) & ~1;
		size_t index = (((size_t)key % block) & ~1 ) | ((size_t)key & 1);
		tte = &table[index + thread_id * block].entry[0];

	}	else {
		tte = first_entry(key);
	}
	gen8 = generation(thread_id);

#endif

	// 上位16bitが合致するTT_ENTRYを探す
	const uint16_t key16 = key >> 48;

	// クラスターのなかから、keyが合致するTT_ENTRYを探す
	for (int i = 0; i < ClusterSize; ++i)
	{
		// returnする条件
		// 1. 空のエントリーを見つけた(そこまではkeyが合致していないので、found==falseにして新規TT_ENTRYのアドレスとして返す)
		// 2. keyが合致しているentryを見つけた。(found==trueにしてそのTT_ENTRYのアドレスを返す)

		// Stockfishのコードだと、1.が成立したタイミングでもgenerationのrefreshをしているが、
		// save()のときにgenerationを書き出すため、このケースにおいてrefreshは必要ない。

		// 1.
		if (!tte[i].key16)
			return found = false, &tte[i];

		// 2.
		if (tte[i].key16 == key16)
		{
#if defined(USE_GLOBAL_OPTIONS)
			// 置換表とTTEntryの世代が異なるなら、信用できないと仮定するフラグ。
			if (GlobalOptions.use_strict_generational_tt)
				if (tte[i].generation() != gen8)
					return found = false, &tte[i];
#endif

			tte[i].set_generation(gen8); // Refresh
			return found = true, &tte[i];
		}
	}

	// 空きエントリーも、探していたkeyが格納されているentryが見当たらなかった。
	// クラスター内のどれか一つを潰す必要がある。

	TTEntry* replace = tte;
	for (int i = 1; i < ClusterSize; ++i)

		// ・深い探索の結果であるものほど価値があるので残しておきたい。depth8 × 重み1.0
		// ・generationがいまの探索generationに近いものほど価値があるので残しておきたい。geration(4ずつ増える)×重み 2.0
		// 以上に基いてスコアリングする。
		// 以上の合計が一番小さいTTEntryを使う。

		if (replace->depth8 - ((259 + gen8 - replace->genBound8) & 0xFC) * 2
		  >   tte[i].depth8 - ((259 + gen8 -   tte[i].genBound8) & 0xFC) * 2)
			replace = &tte[i];

	// generationは256になるとオーバーフローして0になるのでそれをうまく処理できなければならない。
	// a,bが8bitであるとき ( 256 + a - b ) & 0xff のようにすれば、オーバーフローを考慮した引き算が出来る。
	// このテクニックを用いる。
	// いま、
	//   a := generationは下位2bitは用いていないので0。
	//   b := genBound8は下位2bitにはBoundが入っているのでこれはゴミと考える。
	// ( 256 + a - b + c) & 0xfc として c = 3としても結果に影響は及ぼさない、かつ、このゴミを無視した計算が出来る。

	return found = false, replace;
}