|
Packit Service |
310c69 |
/*
|
|
Packit Service |
310c69 |
* Copyright (c) 2020 Red Hat, Inc.
|
|
Packit Service |
310c69 |
*
|
|
Packit Service |
310c69 |
* This program is free software; you can redistribute it and/or
|
|
Packit Service |
310c69 |
* modify it under the terms of the GNU General Public License
|
|
Packit Service |
310c69 |
* as published by the Free Software Foundation; either version 2
|
|
Packit Service |
310c69 |
* of the License, or (at your option) any later version.
|
|
Packit Service |
310c69 |
*
|
|
Packit Service |
310c69 |
* This program is distributed in the hope that it will be useful,
|
|
Packit Service |
310c69 |
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
Packit Service |
310c69 |
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
Packit Service |
310c69 |
* GNU General Public License for more details.
|
|
Packit Service |
310c69 |
*
|
|
Packit Service |
310c69 |
* You should have received a copy of the GNU General Public License
|
|
Packit Service |
310c69 |
* along with this program; if not, write to the Free Software
|
|
Packit Service |
310c69 |
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
|
Packit Service |
310c69 |
* 02110-1301, USA.
|
|
Packit Service |
310c69 |
*
|
|
Packit Service |
310c69 |
* $Id: //eng/uds-releases/jasper/src/uds/cpu.h#1 $
|
|
Packit Service |
310c69 |
*/
|
|
Packit Service |
310c69 |
|
|
Packit Service |
310c69 |
#ifndef CPU_H
|
|
Packit Service |
310c69 |
#define CPU_H
|
|
Packit Service |
310c69 |
|
|
Packit Service |
310c69 |
#include "compiler.h"
|
|
Packit Service |
310c69 |
#include "typeDefs.h"
|
|
Packit Service |
310c69 |
|
|
Packit Service |
310c69 |
/**
|
|
Packit Service |
310c69 |
* The number of bytes in a CPU cache line. In the future, we'll probably need
|
|
Packit Service |
310c69 |
* to move this to a processor-specific file or discover it at compilation
|
|
Packit Service |
310c69 |
* time (or runtime, if sufficiently heterogeneous), but this will do for now.
|
|
Packit Service |
310c69 |
* (Must be a \#define since enums are not proper compile-time constants.)
|
|
Packit Service |
310c69 |
**/
|
|
Packit Service |
310c69 |
#ifdef __PPC__
|
|
Packit Service |
310c69 |
// N.B.: Some PPC processors have smaller cache lines.
|
|
Packit Service |
310c69 |
#define CACHE_LINE_BYTES 128
|
|
Packit Service |
310c69 |
#elif defined(__s390x__)
|
|
Packit Service |
310c69 |
#define CACHE_LINE_BYTES 256
|
|
Packit Service |
310c69 |
#elif defined(__x86_64__) || defined(__aarch64__)
|
|
Packit Service |
310c69 |
#define CACHE_LINE_BYTES 64
|
|
Packit Service |
310c69 |
#else
|
|
Packit Service |
310c69 |
#error "unknown cache line size"
|
|
Packit Service |
310c69 |
#endif
|
|
Packit Service |
310c69 |
|
|
Packit Service |
310c69 |
/**
|
|
Packit Service |
310c69 |
* Minimize cache-miss latency by moving data into a CPU cache before it is
|
|
Packit Service |
310c69 |
* accessed.
|
|
Packit Service |
310c69 |
*
|
|
Packit Service |
310c69 |
* @param address the address to fetch (may be invalid)
|
|
Packit Service |
310c69 |
* @param forWrite must be constant at compile time--false if
|
|
Packit Service |
310c69 |
* for reading, true if for writing
|
|
Packit Service |
310c69 |
**/
|
|
Packit Service |
310c69 |
static INLINE void prefetchAddress(const void *address, bool forWrite)
|
|
Packit Service |
310c69 |
{
|
|
Packit Service |
310c69 |
// forWrite won't won't be a constant if we are compiled with optimization
|
|
Packit Service |
310c69 |
// turned off, in which case prefetching really doesn't matter.
|
|
Packit Service |
310c69 |
if (__builtin_constant_p(forWrite)) {
|
|
Packit Service |
310c69 |
__builtin_prefetch(address, forWrite);
|
|
Packit Service |
310c69 |
}
|
|
Packit Service |
310c69 |
}
|
|
Packit Service |
310c69 |
|
|
Packit Service |
310c69 |
/**
|
|
Packit Service |
310c69 |
* Minimize cache-miss latency by moving a range of addresses into a
|
|
Packit Service |
310c69 |
* CPU cache before they are accessed.
|
|
Packit Service |
310c69 |
*
|
|
Packit Service |
310c69 |
* @param start the starting address to fetch (may be invalid)
|
|
Packit Service |
310c69 |
* @param size the number of bytes in the address range
|
|
Packit Service |
310c69 |
* @param forWrite must be constant at compile time--false if
|
|
Packit Service |
310c69 |
* for reading, true if for writing
|
|
Packit Service |
310c69 |
**/
|
|
Packit Service |
310c69 |
static INLINE void prefetchRange(const void *start,
|
|
Packit Service |
310c69 |
unsigned int size,
|
|
Packit Service |
310c69 |
bool forWrite)
|
|
Packit Service |
310c69 |
{
|
|
Packit Service |
310c69 |
// Count the number of cache lines to fetch, allowing for the address range
|
|
Packit Service |
310c69 |
// to span an extra cache line boundary due to address alignment.
|
|
Packit Service |
310c69 |
const char *address = (const char *) start;
|
|
Packit Service |
310c69 |
unsigned int offset = ((uintptr_t) address % CACHE_LINE_BYTES);
|
|
Packit Service |
310c69 |
size += offset;
|
|
Packit Service |
310c69 |
|
|
Packit Service |
310c69 |
unsigned int cacheLines = (1 + (size / CACHE_LINE_BYTES));
|
|
Packit Service |
310c69 |
while (cacheLines-- > 0) {
|
|
Packit Service |
310c69 |
prefetchAddress(address, forWrite);
|
|
Packit Service |
310c69 |
address += CACHE_LINE_BYTES;
|
|
Packit Service |
310c69 |
}
|
|
Packit Service |
310c69 |
}
|
|
Packit Service |
310c69 |
|
|
Packit Service |
310c69 |
#endif /* CPU_H */
|