Estoy haciendo una investigación para mi Universidad relacionada con un algoritmo de reconstrucción de imágenes para uso médico.mejorar la localidad y disminuir la contaminación de la caché en una implementación de reconstrucción de imágenes médicas
estoy atascado en algo hasta 3 semanas, tengo que mejorar el rendimiento del siguiente código:
for (lor=lor0[mypid]; lor <= lor1[mypid]; lor++)
{
LOR_X = P.symmLOR[lor].x;
LOR_Y = P.symmLOR[lor].y;
LOR_XY = P.symmLOR[lor].xy;
lor_z = P.symmLOR[lor].z;
LOR_Z_X = P.symmLOR[lor_z].x;
LOR_Z_Y = P.symmLOR[lor_z].y;
LOR_Z_XY = P.symmLOR[lor_z].xy;
s0 = P.a2r[lor];
s1 = P.a2r[lor+1];
for (s=s0; s < s1; s++)
{
pixel = P.a2b[s];
v = P.a2p[s];
b[lor] += v * x[pixel];
p = P.symm_Xpixel[pixel];
b[LOR_X] += v * x[p];
p = P.symm_Ypixel[pixel];
b[LOR_Y] += v * x[p];
p = P.symm_XYpixel[pixel];
b[LOR_XY] += v * x[p];
// do Z symmetry.
pixel_z = P.symm_Zpixel[pixel];
b[lor_z] += v * x[pixel_z];
p = P.symm_Xpixel[pixel_z];
b[LOR_Z_X] += v * x[p];
p = P.symm_Ypixel[pixel_z];
b[LOR_Z_Y] += v * x[p];
p = P.symm_XYpixel[pixel_z];
b[LOR_Z_XY] += v * x[p];
}
}
para cualquier persona que quiera saber, el código implementa la función de avance MLEM y todos las variables son FLOAT.
Después de varias pruebas, me di cuenta de que la gran demora estaba en esta parte del código. (ya sabes, la regla 90 - 10).
Más tarde, utilicé Papi (http://cl.cs.utk.edu/papi/) para medir errores de caché de L1D. Como pensé, Papi confirmó que el rendimiento disminuye debido a una mayor cantidad de errores, particularmente para el acceso aleatorio al vector b (de gran tamaño).
Leyendo información en Internet Solo conozco dos opciones para mejorar el rendimiento hasta el momento: mejorar la ubicación de los datos o disminuir la contaminación de los datos.
Para hacer la primera mejora, voy a tratar de cambiar el código de caché de ser conscientes, al igual que se nos propuso por Ulrich Drepper en Lo que todo programador debe saber sobre la memoria (www.akkadia.org/drepper/ cpumemory.pdf) A.1. Multiplicación de matrices.
Creo que bloqueando el SpMV (Multiplicación escasa matriz-vector) mejorará el rendimiento.
Por otro lado, cada vez que el programa intentaba acceder al vector b, teníamos lo que se conoce como contaminación del caché.
¿Hay alguna manera de cargar el valor del vector b con la instrucción SIMD sin usar el caché?
Además, es posible usar una función como void _mm_stream_ps (float * p, __m128 a) para almacenar UN valor de flotación en el vector b sin contaminar el Cache?
No puedo usar _mm_stream_ps porque siempre almacena 4 flotantes pero el acceso al vector b es claramente aleatorio.
Espero ser claro en mi dilema.
Más información: v es el valor de columna de una tienda de matriz dispersa con formato CRS. Me di cuenta de que se podía hacer otra optimización si intentaba cambiar el formato CRS a otro, sin embargo, como dije antes, hice varias pruebas durante meses y sé que la disminución del rendimiento está relacionada con el acceso aleatorio en el vector b. de 400.000.000 L1D Faltas Puedo ir a 100 ~ Faltas cuando no almaceno en el vector b.
Gracias.
+1 para una pregunta bien formada con abundante información de antecedentes y detalles de lo que ha intentado hasta ahora. –